diff --git a/iped-api/src/main/java/iped/configuration/Configurable.java b/iped-api/src/main/java/iped/configuration/Configurable.java index 51ffb60a33..0e40afed77 100644 --- a/iped-api/src/main/java/iped/configuration/Configurable.java +++ b/iped-api/src/main/java/iped/configuration/Configurable.java @@ -64,4 +64,22 @@ default public void processConfigs(List resources) throws IOException { */ void setConfiguration(T config); + /** + * Writes a configuration resource found after applying the lookup filter. + * + * @param resource + * a configuration path where to save the necessary data. + */ + public void save(Path resource); + + + /** + * Resets the configurable state. Configurables that implements loading tecniques from multiple + * sources should use this to reset before reload, clearing any old loaded source. + * + * @param resource + * a configuration path where to save the necessary data. + */ + public void reset(); + } diff --git a/iped-api/src/main/java/iped/configuration/IConfigurationDirectory.java b/iped-api/src/main/java/iped/configuration/IConfigurationDirectory.java index 995701a775..35befff3d4 100644 --- a/iped-api/src/main/java/iped/configuration/IConfigurationDirectory.java +++ b/iped-api/src/main/java/iped/configuration/IConfigurationDirectory.java @@ -8,16 +8,14 @@ public interface IConfigurationDirectory { public static final String IPED_CONF_PATH = "iped.configPath"; - public static final String IPED_ROOT = "iped.root"; - public static final String IPED_APP_ROOT = "iped.app.root"; public void addPath(Path path); public List getResourceLookupFolders(); - public List lookUpResource(Predicate predicate) throws IOException; - public List lookUpResource(Configurable configurable) throws IOException; + + public String getName(); } diff --git a/iped-api/src/main/java/iped/exception/UIException.java b/iped-api/src/main/java/iped/exception/UIException.java new file mode 100644 index 0000000000..0371f85e14 --- /dev/null +++ b/iped-api/src/main/java/iped/exception/UIException.java @@ -0,0 +1,15 @@ +package iped.exception; + +/* + * @created 02/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +public class UIException extends Throwable{ + + + public UIException(String s) { + super(s); + } +} diff --git a/iped-app/pom.xml b/iped-app/pom.xml index 9d0e7045bc..53afdd8607 100644 --- a/iped-app/pom.xml +++ b/iped-app/pom.xml @@ -9,18 +9,29 @@ iped-app jar - + ${project.parent.build.directory}/release/iped-${project.version} ${resources.dir}/../.. - + iped iped-engine ${project.version} + + + com.fifesoft + rsyntaxtextarea + 3.3.2 + + + com.fifesoft + autocomplete + 3.3.1 + iped iped-geo @@ -53,7 +64,7 @@ 5d6b903557dac49a925a7a62d5c6592bd07482c5 - + @@ -94,7 +105,7 @@ analyze - + unpack-jre package @@ -571,7 +582,7 @@ - + copy-dependencies package @@ -632,7 +643,7 @@ iped ${release.dir} true - + false true @@ -641,32 +652,10 @@ iped/app/splash/iped.png - + - create-search-jar @@ -676,7 +665,7 @@ iped-search-app ${lib.dir} true - + false true @@ -684,7 +673,7 @@ iped/app/splash/iped.png - + @@ -729,7 +718,7 @@ - + org.apache.maven.plugins maven-resources-plugin @@ -859,5 +848,5 @@ - + diff --git a/iped-app/resources/config/conf/CarverConfig.xml b/iped-app/resources/config/conf/CarverConfig.xml index a3c0d7b8e1..05c8d367a6 100644 --- a/iped-app/resources/config/conf/CarverConfig.xml +++ b/iped-app/resources/config/conf/CarverConfig.xml @@ -432,4 +432,4 @@ --> - \ No newline at end of file + diff --git a/iped-app/resources/localization/iped-desktop-messages.properties b/iped-app/resources/localization/iped-desktop-messages.properties index 8a4504e69e..0f2a7af376 100644 --- a/iped-app/resources/localization/iped-desktop-messages.properties +++ b/iped-app/resources/localization/iped-desktop-messages.properties @@ -29,6 +29,7 @@ AppLazyInitializer.errorTitle=Initializing error AppListener.NoHits=No hits AppListener.UncheckAll=Do you confirm unchecking all items? AppListener.UncheckAll.Title=Confirmation +AppMain.error.Title=Initializing error AppMain.NoCasesFile=Case list file not found: AppMain.warn.Title=Initializing warn BookmarksController.HistoryDelimiter=-----------------------History----------------------- @@ -77,7 +78,65 @@ BookmarksManager.UpdateTooltip=Update comments BookmarksManager.AlreadyExists=Bookmark name already exists! BookmarksTreeModel.NoBookmarks=[No Bookmarks] BookmarksTreeModel.RootName=Bookmarks +Case.New=New +Case.NewCase=New Case +Case.Open=Open +Case.OpenCase=Open Case +Case.Options=Options +Case.ProcessingOptions=Processing Options +Case.CaseName=Name +Case.CaseOutput=Output Folder +Case.CaseChoose=Choose... +Case.NonEmptyDirectoryAlert=The "{0}" directory is not empty. The "{1}" directory will be created. Do you wish to continue? +Case.DatasourceType=Datasource Type +Case.DatasourceInput=Datasource Input +Case.DataSourceName=Datasource Name +Case.DataSourceType=Type +Case.PersonId=Person Id +Case.BusinessId=Business Id +Case.PersonIdMask= +Case.BusinessIdMask= +Case.AddDatasource=Add Datasource +Case.RemoveDatasource=Remove Datasource +Case.AddInput=Add Input +Case.RemoveFile=Remove +Case.CaseSaveError=An error occurred while saving the case: {0} +Case.CaseLoadError=An error occurred while loading the case: {0} +Case.CaseFile=Iped Case Files +Case.SaveCase=Save +Case.Cancel=Cancel +Case.enableLedDie=Enable LED DIE +Case.exportFileProps=Export File Properties +Case.enableLanguageDetect=Enable Language Detection +Case.enableRegexSearch=Enable Regex Search +Case.enableNamedEntityRecogniton=Enable Entity Recognition +Case.enableGraphGeneration=Enable Graph Generation +Case.indexUnknownFiles=Index Unknown Files +Case.addUnallocated=Process Unallocated +Case.enableOCR=Enable OCR +Case.enableLedDieHelp=Enables nudity detection. +Case.exportFilePropsHelp=Exports the properties of all files to "Lista de Arquvivos.csv". +Case.enableLanguageDetectHelp=Enables the detection of more than 70 languages. +Case.enableRegexSearchHelp=Search the extracted text for regular expressions. +Case.enableNamedEntityRecognitonHelp=Enables EXPERIMENTAL named entities detection feature. Additional configuration is necessary. +Case.enableGraphGenerationHelp=Enables EXPERIMENTAL graph generation feature. Depends on regex search. +Case.indexUnknownFilesHelp=Indexes unknown files as binaries, page files, unallocated, etc. +Case.addUnallocatedHelp=Adds and processes unallocated areas via sleuthkit. +Case.enableOCRHelp=Enables OCR at images and PDFs. May increase the processing time. +Case.Yes=Yes +Case.No=No +Case.ProcessCase=Process +Case.OptionsSaved=Options saved to file {0}. +Case.OptionsSaveError==An error occurred while saving: {0} +Case.PERSON=Person +Case.BUSINESS=Business +Case.GENERIC=Generic +Case.PersonIdRegex= +Case.BusinessIdRegex= +Case.Profile=Profile +Case.ProfileHelp=Processing profile selection. CategoryTreeModel.RootName=Categories +CategoryTreeModel.Uncategorizables=Uncategorized ColumnsManager.Advanced=Advanced ColumnsManager.All=All ColumnsManager.Audio=Audio @@ -102,19 +161,19 @@ ColumnsManager.AutoManageCols=Manage columns automatically (slower) ColumnsManager.LoadingCols=Loading used columns... ColumnsManager.Filter=[Type to filter] ColumnsManager.WindowsEvt=Windows Events -CopyProperties.Copying=Copying +CopyProperties.Copying=Copying CopyProperties.CSVDateFormat=MM/dd/yyyy HH:mm:ss z CopyProperties.CSVDelimiter=, -CopyProperties.from=\ of +CopyProperties.from=\ of DuplicatesTableModel.Duplicates=\ Duplicates -ExportFiles.Copying=Copying -ExportFiles.of=\ of -ExportFilesToZip.Copying=Copying -ExportFilesToZip.from=\ of -ExportFileTree.Copied=Copied +ExportFiles.Copying=Copying +ExportFiles.of=\ of +ExportFilesToZip.Copying=Copying +ExportFilesToZip.from=\ of +ExportFileTree.Copied=Copied ExportFileTree.ExportError=Error exporting files. Check permissions and available space.\n -ExportFileTree.from=\ of -ExportIndexedTerms.Exported=Exported +ExportFileTree.from=\ of +ExportIndexedTerms.Exported=Exported ExportIndexedTerms.ofWords=\ of words. ExportToZIP.DefaultName=ExportedFiles.zip ExportToZIP.DefaultPath=/home/caine/DADOS_EXPORTADOS @@ -162,7 +221,7 @@ GraphAnalysis.Search=Search GraphAnalysis.Add=Add GraphAnalysis.Cancel=Cancel GraphAnalysis.Export=Export -GraphAnalysis.Id +GraphAnalysis.Id=Id GraphAnalysis.Type=Type GraphAnalysis.Quantity=Quantity GraphAnalysis.Property=Property @@ -187,9 +246,9 @@ GraphAnalysis.MultiGraphError=Could not create multicase graph, check log! GraphAnalysis.MultiGraphOk=Multicase graph created. GraphAnalysis.InitialGraphMsg=Initial graph view ready. It just includes the most linked entities. KeywordListImporter.BookmarkPrefix=Results of search for: -KeywordListImporter.Msg.1=Imported -KeywordListImporter.Msg.2=\ keywords with hits of -KeywordListImporter.SyntaxError=Syntax error in the following expressions: +KeywordListImporter.Msg.1=Imported +KeywordListImporter.Msg.2=\ keywords with hits of +KeywordListImporter.SyntaxError=Syntax error in the following expressions: HashDialog.MD5Title=MD5 Hash of exported ZIP ImageSimilarity.ExternalError=Unable to open the selected image. ImageSimilarity.ExternalTitle=External Similar Image @@ -329,11 +388,11 @@ ResultTableRowSorter.Sorting=Sorting... RowComparator.SortCanceled=Sort Canceled. SearchStateFilter.BookmarksFile=Bookmarks File SubitemTableModel.Subitens=\ Attachs/Subitems -TextParserListener.Found=Found +TextParserListener.Found=Found TextParserListener.hits=\ hits TreeViewModel.RootName=Evidences UISearcher.Canceled=Search canceled\! -UISearcher.Error.Msg=Query syntax error: +UISearcher.Error.Msg=Query syntax error: UISearcher.Error.Title=Error UnsupportedIcon.Unavailable=Thumbnail not supported ViewerController.OfficeViewerUnSupported=Office viewer not supported in java 32bits anymore! Please install a java 64bits. @@ -441,4 +500,159 @@ FieldValuePopupMenu.LessThan=Filter less than... FieldValuePopupMenu.Equals=Equals to... FieldValuePopupMenu.StartsWith=Starts with... FieldValuePopupMenu.Clear=Clear -FieldValuePopupMenu.Filter=Filter \ No newline at end of file +FieldValuePopupMenu.Filter=Filter +Home.StartNewCase=START NEW CASE +Home.OpenCase=OPEN CASE +Home.Config=CONFIGURATIONS +Home.LocalEnviromentConfiguration=Local environment configuration +Home.DefaultThreadValue=Set default thread value +Home.ChooseDefaultIndexTempFolder=Choose default index temp folder +Home.DefaultIndexTempToolTip=Set "Default" as Index Temp value (Default is your O.S. default temp path) +Home.Language=Language +Home.NumberOfThreads=Number of Threads +Home.TempFolder=Temporary directory +Home.HashDatabase=HashDB directory +Home.TSKJar=TSK Jar Directory +Home.TSKJarDialogTtitle=Choose TSK JAR file +Home.OptionalPluginsPath=Optional plugins directory +Home.OptPluginDialogTtitle=Choose optional plugins directory +Home.IndexTempOnSSDLabel=Check this option if the "Temp`s Directory" is on an SSD device +Home.InformHashDBFile=Inform the HashDB File +Home.Save=Save +Home.Cancel=Cancel +Home.Next=Next +Home.Back=Back +Home.Select=Select +Home.Active=Active +Home.Inactive=Inactive +Home.LanguagePtBR=Brazilian portuguese +Home.LanguageEN=English +Home.LanguageIT=Italian +Home.LanguageDE=German +Home.LanguageEsAr=Argentine Spanish +Home.LanguageChangeMessage=You have selected a different language. Restart the application to apply the selected language. +Home.LanguageChangeTitle=Language modification +Home.CaseInformation=Case Information +Home.CaseInformationTollTip=Case Detail +Home.Evidences=Evidences +Home.EvidencesToolTip=List of evidence to be processed +Home.ProcessOptions=Process options +Home.ProcessOptionsToolTip=Process task selection page +Home.ProcessingTab=Processing +Home.ProcessingTabTooltip=Processing evolution watch +Home.NewCase.CaseOutput=*Case output +Home.NewCase.ChooseCaseOutput=Choose case output +Home.NewCase.IsCaseOutputOnSSD=Is case output on a SSD device? +Home.NewCase.IsCaseOutputOnSSDToolTip=Enable if case output is on SSD. If enabled, index is created directly in case folder, not in indexTemp, so you will need less free space in temp folder. +Home.NewCase.CaseOutputRequired=Case output is required +Home.NewCase.CaseOutputRequiredTitle=Case output +Home.NewCase.CaseOutputPermission=Read and write permission is required on the case output folder. +Home.NewCase.CaseOutputPermissionTitle=Case output folder +Home.NewCase.CaseOutPutOptionsRequired=You need to select an option for the case output folder. +Home.NewCase.SaveCaseData=Save case data +Home.NewCase.LoadCaseData=Load case data +Home.NewCase.ChooseCaseInfoFileOutput=Choose case info file output +Home.NewCase.ChooseCaseInfoFile=Choose case info file source +Home.ExistentCaseAlert=A case already exists in the specified case output folder. Choose an option below or select other case output folder: +Home.AppendExistentCase=Append - Append this case to the existing one +Home.ContinueExistentCase=Continue - Continue the existing process +Home.RestartExistentCase=Restart - Restart the existing process +Home.Evidences.AddFolder=Add folder +Home.Evidences.AddFile=Add file +Home.Evidences.AddImagesRecursively=Add images recursively +Home.Evidences.AddDisk=Add disk +Home.Evidences.SelectFolder=Select folder +Home.Evidences.SelectFile=Select file +Home.Evidences.AddFileTitle=Add file +Home.Evidences.ChooseSourceFolder=Select search root folder +Home.Evidences.ImageSearchError=Image search error +Home.Evidences.PathMustBeDirectory=Path must be a directory. +Home.Evidences.Title=Evidences +Home.Evidences.Table.FileName=File name +Home.Evidences.Table.Alias=Alias +Home.Evidences.Table.Path=Path +Home.Evidences.Table.Options=Options +Home.Evidences.DialogTitle=Evidences details +Home.Evidences.Dialog.FileName=File name: +Home.Evidences.Dialog.Path=File Path: +Home.Evidences.Dialog.Alias=Alias: +Home.Evidences.Dialog.EvidenceDesc=Evidence description: +Home.Evidences.Dialog.Password=Password (APFS Image): +Home.Evidences.Dialog.TimeZone=TimeZone (FAT FS): +Home.Evidences.Dialog.BlockSize=Block size (0 = default): +Home.Evidences.DisksDialog.Title=Choose the disk to be processed +Home.Evidences.DisksDialog.Name=Name +Home.Evidences.DisksDialog.Model=Model +Home.Evidences.DisksDialog.Size=Size +Home.Evidences.DisksDialog.Serial=Serial +Home.Evidences.DisksDialog.Select=Select +Home.Evidences.DisksDialog.NotAdmin=You must be admin to process physical drives +Home.Evidences.NoEvidencesAlert=You need to choose at least one evidence to continue +Home.Evidences.NoEvidencesAlertTitle=No evidences selected +Home.ProcOptions.Title=Process options +Home.ProcOptions.ExecProfile=Execution profile: +Home.ProcOptions.NewProfile=New profile name: +Home.ProcOptions.ButtonStarExecTooltip=Save or cancel profile edition before continue. +Home.ProcOptions.CreateNewProfile=Create new profile +Home.ProcOptions.AddScriptTask=Add script task +Home.ProcOptions.StartProcessing=Start processing +Home.ProcOptions.Table.Options=Options +Home.ProcOptions.ScriptAlreadyExists=Script destination folder already has a file with this name. Please change the name of the source script first. +Home.ProcessManager.StartingProcess=Hang on, we are starting your processing.. +Home.ProcessManager.ProcessFailed=IPED execution failed.. +Home.ProcessManager.ProcessRunning=IPED is processing.. +Home.ProcessManager.ProcessFinished=Process finished successfully!! +Home.ProcessManager.BackToCaseInfo=Back to case info +Home.ProcessManager.ShowTerminalLog=View Processing Log +Home.ProcessManager.OpenCase=Open case +Home.ProcessManager.OpenCaseMsg=Wait... +Home.ProcessManager.TerminalLog=Terminal log +Home.ProcessManager.ExitApplication=Exit application +Home.OpenCase.OpenCase=Open Case(s) +Home.OpenCase.AddCaseToList=Add a case to the list +Home.OpenCase.RemoveCaseFromList=Remove the case from list +Home.OpenCase.SelectCaseFolder=Select case folder +Home.OpenCase.OpenAllCasesInTheList=Open all cases in the list +Home.OpenCase.EmptyCaseMessage=You need add at least one case to list +Home.OpenCase.EmptyCaseMessageTitle=Empty case list +Home.OpenCase.CaseLocation=Case location +Home.OpenCase.CaseTableHeader=CASE LIST +Home.IPEDMimeSeachList.showTikaMimeTypes=Show Tika mime types +Home.configurables.AdvancedPanelLabel=Advanced +Home.configurables.BasicPanelLabel=Basic configuration +Home.configurables.BasicCarverPanelLabel=Carvers list +Home.configurables.BasicParsersPanelLabel=Parsers list +ScriptEditPanel.File=File: +ScriptEditPanel.SelectTemplateLabel=Select Template: +ScriptEditPanel.StartEditing=Start editing +ScriptEditPanel.Preview=Preview +ScriptEditPanel.ImportScript.tooltip=Load script from file +ScriptEditPanel.ImportScript=Import script +iped.app.home.configurables.ParsersConfigurablePanel.EmptyNameError=Parser name field empty. +iped.app.home.configurables.ParsersConfigurablePanel.EmptyCommandError=Command field empty. +iped.app.home.configurables.ParsersConfigurablePanel.EmptyMimeTypeError=Mime-types field empty. +iped.app.home.configurables.ParsersConfigurablePanel.InvalidMimeTypeError=Invalid mimetype +iped.app.home.configurables.ParsersConfigurablePanel.UnregisteredMimeTypeError="Mime type specified is not registered +iped.app.home.configurables.ParsersConfigurablePanel.EmptyCharsetError=Charset field empty. +iped.app.home.configurables.ParsersConfigurablePanel.InvalidFirstLinesToSkipError=Invalid value informed as number of first lines to skip. +iped.app.home.configurables.ParsersConfigurablePanel.InvalidCharsetError=Invalid charset. +iped.app.home.configurables.ParsersConfigurablePanel.EditVetoError=Edition of external parser in course. +iped.app.home.configurables.ParsersConfigurablePanel.CreateExternalParser=Create external parser +iped.app.home.configurables.ParsersConfigurablePanel.NewExternalParserPanel=New external Parser +ScriptEditPanel.scriptScopeWarn=The script file is saved in shared script folder, affecting all profile configurations. Do you want to continue editing? +ReportDialog.InvestigatedNames=Investigated Name +ReportDialog.organizationName=Organization Name +ReportDialog.contact=Contact +ReportDialog.caseNotes=Case notes +Home.OpenCase.InavlidCasePath=Invalid Case Path +Home.OpenCase.NoSearchApp=IPED-SearchApp not found +Home.OpenCase.CaseNotFinished=The case process is not finished +Home.OpenCase.CaseV3NotSupported=Cases from version 3 are not supported +Home.NewCase.OpenCaseFileDialogTitle=Overwrite information? +Home.NewCase.OpenCaseFileDialogMessage=Do you want to overwrite existing information with information from the file? +Home.ProcessManager.ExistentCaseAlertTitle=Existing case +Home.ProcessManager.ExistentCaseAlertMessage=A case already exists in the directory in the case destination folder. What do you wanna do? +Home.Evidences.SkippedFoldersOnRecursiveEvidenceFind=Some folders were inaccessible and skipped when searching for evidences +Home.Evidences.SkippedFoldersOnRecursiveEvidenceFindAlertTitle=Skipped Folders +Home.Configurable.Enable=Enable +Home.Configurable.Disable=Disable \ No newline at end of file diff --git a/iped-app/resources/localization/iped-desktop-messages_de_DE.properties b/iped-app/resources/localization/iped-desktop-messages_de_DE.properties index 79a06db85b..a72318f5db 100644 --- a/iped-app/resources/localization/iped-desktop-messages_de_DE.properties +++ b/iped-app/resources/localization/iped-desktop-messages_de_DE.properties @@ -78,6 +78,65 @@ BookmarksManager.AlreadyExists=Lesezeichen ist bereits vorhanden! BookmarksTreeModel.NoBookmarks=[Keine Lesezeichen] BookmarksTreeModel.RootName=Lesezeichen CategoryTreeModel.RootName=Kategorien +Case.New=New[TBT] +Case.NewCase=New Case[TBT] +Case.Open=Open[TBT] +Case.OpenCase=Open Case[TBT] +Case.Options=Options[TBT] +Case.ProcessingOptions=Processing Options[TBT] +Case.CaseName=Name[TBT] +Case.CaseOutput=Output Folder[TBT] +Case.CaseChoose=Choose...[TBT] +Case.NonEmptyDirectoryAlert=The "{0}" directory is not empty. The "{1}" directory will be created. Do you wish to continue?[TBT] +Case.DatasourceType=Datasource Type[TBT] +Case.DatasourceInput=Datasource Input[TBT] +Case.DataSourceName=Datasource Name[TBT] +Case.DataSourceType=Type[TBT] +Case.PersonId=Person Id[TBT] +Case.BusinessId=Business Id[TBT] +Case.PersonIdMask= +Case.BusinessIdMask= +Case.AddDatasource=Add Datasource[TBT] +Case.RemoveDatasource=Remove Datasource[TBT] +Case.AddInput=Add Input[TBT] +Case.RemoveFile=Remove[TBT] +Case.CaseSaveError=An error occurred while saving the case: {0}[TBT] +Case.CaseLoadError=An error occurred while loading the case: {0}[TBT] +Case.CaseFile=Iped Case Files[TBT] +Case.SaveCase=Save[TBT] +Case.Cancel=Cancel[TBT] +Case.enableLedDie=Enable LED DIE[TBT] +Case.exportFileProps=Export File Properties[TBT] +Case.enableLanguageDetect=Enable Language Detection[TBT] +Case.enableRegexSearch=Enable Regex Search[TBT] +Case.enableNamedEntityRecogniton=Enable Entity Recognition[TBT] +Case.enableGraphGeneration=Enable Graph Generation[TBT] +Case.indexUnknownFiles=Index Unknown Files[TBT] +Case.addUnallocated=Process Unallocated[TBT] +Case.enableOCR=Enable OCR[TBT] +Case.enableLedDieHelp=Enables nudity detection.[TBT] +Case.exportFilePropsHelp=Exports the properties of all files to "Lista de Arquvivos.csv".[TBT] +Case.enableLanguageDetectHelp=Enables the detection of more than 70 languages.[TBT] +Case.enableRegexSearchHelp=Search the extracted text for regular expressions.[TBT] +Case.enableNamedEntityRecognitonHelp=Enables EXPERIMENTAL named entities detection feature. Additional configuration is necessary.[TBT] +Case.enableGraphGenerationHelp=Enables EXPERIMENTAL graph generation feature. Depends on regex search.[TBT] +Case.indexUnknownFilesHelp=Indexes unknown files as binaries, page files, unallocated, etc.[TBT] +Case.addUnallocatedHelp=Adds and processes unallocated areas via sleuthkit.[TBT] +Case.enableOCRHelp=Enables OCR at images and PDFs. May increase the processing time.[TBT] +Case.Yes=Yes[TBT] +Case.No=No[TBT] +Case.ProcessCase=Process[TBT] +Case.OptionsSaved=Options saved to file {0}.[TBT] +Case.OptionsSaveError==An error occurred while saving: {0}[TBT] +Case.PERSON=Person[TBT] +Case.BUSINESS=Business[TBT] +Case.GENERIC=Generic[TBT] +Case.PersonIdRegex= +Case.BusinessIdRegex= +Case.Profile=Profile[TBT] +Case.ProfileHelp=Processing profile selection.[TBT] +CategoryTreeModel.RootName=Categories[TBT] +CategoryTreeModel.Uncategorizables=Uncategorized[TBT] ColumnsManager.Advanced=Erweitert ColumnsManager.All=Alle ColumnsManager.Audio=Audio @@ -162,7 +221,7 @@ GraphAnalysis.Search=Suche GraphAnalysis.Add=Hinzufügen GraphAnalysis.Cancel=Abbrechen GraphAnalysis.Export=Export -GraphAnalysis.Id +GraphAnalysis.Id=Id GraphAnalysis.Type=Typ GraphAnalysis.Quantity=Menge GraphAnalysis.Property=Eigenschaft @@ -441,4 +500,159 @@ FieldValuePopupMenu.LessThan=Filter less than...(TBT) FieldValuePopupMenu.Equals=Equals to...(TBT) FieldValuePopupMenu.StartsWith=Starts with...(TBT) FieldValuePopupMenu.Clear=Clear(TBT) -FieldValuePopupMenu.Filter=Filter(TBT) \ No newline at end of file +FieldValuePopupMenu.Filter=Filter(TBT) +Home.StartNewCase=START NEW CASE [TBT] +Home.OpenCase=OPEN CASE [TBT] +Home.Config=CONFIGURATIONS [TBT] +Home.LocalEnviromentConfiguration=Local environment configuration [TBT] +Home.DefaultThreadValue=Set default thread value [TBT] +Home.ChooseDefaultIndexTempFolder=Choose default index temp folder [TBT] +Home.DefaultIndexTempToolTip=Set "Default" as Index Temp value (Default is your O.S. default temp path) [TBT] +Home.Language=Language [TBT] +Home.NumberOfThreads=Number of Threads [TBT] +Home.TempFolder=Temporary directory [TBT] +Home.HashDatabase=HashDB directory [TBT] +Home.TSKJar=TSK Jar Directory [TBT] +Home.TSKJarDialogTtitle=Choose TSK JAR file [TBT] +Home.OptionalPluginsPath=Optional plugins directory [TBT] +Home.OptPluginDialogTtitle=Choose optional plugins directory [TBT] +Home.IndexTempOnSSDLabel=Check this option if the "Temp`s Directory" is on an SSD device [TBT] +Home.InformHashDBFile=Inform the HashDB File [TBT] +Home.Save=Save [TBT] +Home.Cancel=Cancel [TBT] +Home.Next=Next [TBT] +Home.Back=Back [TBT] +Home.Select=Select [TBT] +Home.Active=Active [TBT] +Home.Inactive=Inactive [TBT] +Home.LanguagePtBR=Brazilian portuguese [TBT] +Home.LanguageEN=English [TBT] +Home.LanguageIT=Italian [TBT] +Home.LanguageDE=German [TBT] +Home.LanguageEsAr=Argentine Spanish [TBT] +Home.LanguageChangeMessage=You have selected a different language. Restart the application to apply the selected language. [TBT] +Home.LanguageChangeTitle=Language modification [TBT] +Home.CaseInformation=Case Information [TBT] +Home.CaseInformationTollTip=Case Detail [TBT] +Home.Evidences=Evidences [TBT] +Home.EvidencesToolTip=List of evidence to be processed [TBT] +Home.ProcessOptions=Process options [TBT] +Home.ProcessOptionsToolTip=Process task selection page [TBT] +Home.ProcessingTab=Processing [TBT] +Home.ProcessingTabTooltip=Processing evolution watch [TBT] +Home.NewCase.CaseOutput=*Case output [TBT] +Home.NewCase.ChooseCaseOutput=Choose case output [TBT] +Home.NewCase.IsCaseOutputOnSSD=Is case output on a SSD device? [TBT] +Home.NewCase.IsCaseOutputOnSSDToolTip=Enable if case output is on SSD. If enabled, index is created directly in case folder, not in indexTemp, so you will need less free space in temp folder. [TBT] +Home.NewCase.CaseOutputRequired=Case output is required [TBT] +Home.NewCase.CaseOutputRequiredTitle=Case output [TBT] +Home.NewCase.CaseOutputPermission=Read and write permission is required on the case output folder. [TBT] +Home.NewCase.CaseOutputPermissionTitle=Case output folder [TBT] +Home.NewCase.CaseOutPutOptionsRequired=You need to select an option for the case output folder. [TBT] +Home.NewCase.SaveCaseData=Save case data [TBT] +Home.NewCase.LoadCaseData=Load case data [TBT] +Home.NewCase.ChooseCaseInfoFileOutput=Choose case info file output [TBT] +Home.NewCase.ChooseCaseInfoFile=Choose case info file source [TBT] +Home.ExistentCaseAlert=A case already exists in the specified case output folder. Choose an option below or select other case output folder: [TBT] +Home.AppendExistentCase=Append - Append this case to the existing one [TBT] +Home.ContinueExistentCase=Continue - Continue the existing process [TBT] +Home.RestartExistentCase=Restart - Restart the existing process [TBT] +Home.Evidences.AddFolder=Add folder [TBT] +Home.Evidences.AddFile=Add file [TBT] +Home.Evidences.AddImagesRecursively=Add images recursively [TBT] +Home.Evidences.AddDisk=Add disk [TBT] +Home.Evidences.SelectFolder=Select folder [TBT] +Home.Evidences.SelectFile=Select file [TBT] +Home.Evidences.AddFileTitle=Add file [TBT] +Home.Evidences.ChooseSourceFolder=Select search root folder [TBT] +Home.Evidences.ImageSearchError=Image search error [TBT] +Home.Evidences.PathMustBeDirectory=Path must be a directory. [TBT] +Home.Evidences.Title=Evidences [TBT] +Home.Evidences.Table.FileName=File name [TBT] +Home.Evidences.Table.Alias=Alias [TBT] +Home.Evidences.Table.Path=Path [TBT] +Home.Evidences.Table.Options=Options [TBT] +Home.Evidences.DialogTitle=Evidences details [TBT] +Home.Evidences.Dialog.FileName=File name: [TBT] +Home.Evidences.Dialog.Path=File Path: [TBT] +Home.Evidences.Dialog.Alias=Alias: [TBT] +Home.Evidences.Dialog.EvidenceDesc=Evidence description: [TBT] +Home.Evidences.Dialog.Password=Password (APFS Image): [TBT] +Home.Evidences.Dialog.TimeZone=TimeZone (FAT FS): [TBT] +Home.Evidences.Dialog.BlockSize=Block size (0 = default): [TBT] +Home.Evidences.DisksDialog.Title=Choose the disk to be processed [TBT] +Home.Evidences.DisksDialog.Name=Name [TBT] +Home.Evidences.DisksDialog.Model=Model [TBT] +Home.Evidences.DisksDialog.Size=Size [TBT] +Home.Evidences.DisksDialog.Serial=Serial [TBT] +Home.Evidences.DisksDialog.Select=Select [TBT] +Home.Evidences.DisksDialog.NotAdmin=You must be admin to process physical drives[TBT] +Home.Evidences.NoEvidencesAlert=You need to choose at least one evidence to continue [TBT] +Home.Evidences.NoEvidencesAlertTitle=No evidences selected [TBT] +Home.ProcOptions.Title=Process options [TBT] +Home.ProcOptions.ExecProfile=Execution profile: [TBT] +Home.ProcOptions.NewProfile=New profile name: [TBT] +Home.ProcOptions.ButtonStarExecTooltip=Save or cancel profile edition before continue. [TBT] +Home.ProcOptions.CreateNewProfile=Create new profile [TBT] +Home.ProcOptions.AddScriptTask=Add script task [TBT] +Home.ProcOptions.StartProcessing=Start processing [TBT] +Home.ProcOptions.Table.Options=Options [TBT] +Home.ProcOptions.ScriptAlreadyExists=Script destination folder already has a file with this name. Please change the name of the source script first. [TBT] +Home.ProcessManager.StartingProcess=Hang on, we are starting your processing.. [TBT] +Home.ProcessManager.ProcessFailed=IPED execution failed.. [TBT] +Home.ProcessManager.ProcessRunning=IPED is processing.. [TBT] +Home.ProcessManager.ProcessFinished=Process finished successfully!! [TBT] +Home.ProcessManager.BackToCaseInfo=Back to case info [TBT] +Home.ProcessManager.ShowTerminalLog=View Processing Log [TBT] +Home.ProcessManager.OpenCase=Open case [TBT] +Home.ProcessManager.OpenCaseMsg=Wait... [TBT] +Home.ProcessManager.TerminalLog=Terminal log [TBT] +Home.ProcessManager.ExitApplication=Exit application [TBT] +Home.OpenCase.OpenCase=Open Case(s) [TBT] +Home.OpenCase.AddCaseToList=Add a case to the list [TBT] +Home.OpenCase.RemoveCaseFromList=Remove the case from list [TBT] +Home.OpenCase.SelectCaseFolder=Select case folder [TBT] +Home.OpenCase.OpenAllCasesInTheList=Open all cases in the list [TBT] +Home.OpenCase.EmptyCaseMessage=You need add at least one case to list [TBT] +Home.OpenCase.EmptyCaseMessageTitle=Empty case list [TBT] +Home.OpenCase.CaseLocation=Case location [TBT] +Home.OpenCase.CaseTableHeader=CASE LIST [TBT] +Home.IPEDMimeSeachList.showTikaMimeTypes=Show Tika mime types [TBT] +Home.configurables.AdvancedPanelLabel=Advanced [TBT] +Home.configurables.BasicPanelLabel=Basic configuration [TBT] +Home.configurables.BasicCarverPanelLabel=Carvers list [TBT] +Home.configurables.BasicParsersPanelLabel=Parsers list [TBT] +ScriptEditPanel.File=File:[TBT] +ScriptEditPanel.SelectTemplateLabel=Select Template:[TBT] +ScriptEditPanel.StartEditing=Start editing[TBT] +ScriptEditPanel.Preview=Preview[TBT] +ScriptEditPanel.ImportScript.tooltip=Load script from file[TBT] +ScriptEditPanel.ImportScript=Import script[TBT] +iped.app.home.configurables.ParsersConfigurablePanel.EmptyNameError=Parser name field empty. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.EmptyCommandError=Command field empty. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.EmptyMimeTypeError=Mime-types field empty. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.InvalidMimeTypeError=Invalid mimetype [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.UnregisteredMimeTypeError="Mime type specified is not registered [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.EmptyCharsetError=Charset field empty. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.InvalidFirstLinesToSkipError=Invalid value informed as number of first lines to skip. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.InvalidCharsetError=Invalid charset. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.EditVetoError=Edition of external parser in course. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.CreateExternalParser=Create external parser [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.NewExternalParserPanel=New external Pars [TBT]er +ScriptEditPanel.scriptScopeWarn=The script file is saved in shared script folder, affecting all profile configurations. Do you want to continue editing? [TBT] +ReportDialog.InvestigatedNames=Investigated Name [TBT] +ReportDialog.organizationName=Organization Name [TBT] +ReportDialog.contact=Contact [TBT] +ReportDialog.caseNotes=Case notes [TBT] +Home.OpenCase.InavlidCasePath=Invalid Case Path[TBT] +Home.OpenCase.NoSearchApp=IPED-SearchApp not found [TBT] +Home.OpenCase.CaseNotFinished=The case process is not finished [TBT] +Home.OpenCase.CaseV3NotSupported=Cases from version 3 are not supported[TBT] +Home.NewCase.OpenCaseFileDialogTitle=Overwrite information? [TBT] +Home.NewCase.OpenCaseFileDialogMessage=Do you want to overwrite existing information with information from the file? [TBT] +Home.ProcessManager.ExistentCaseAlertMessage=A case already exists in the directory in the case destination folder. What do you wanna do? [TBT] +Home.ProcessManager.ExistentCaseAlertTitle=Existing case [TBT] +Home.Evidences.SkippedFoldersOnRecursiveEvidenceFind=Some folders were inaccessible and skipped when searching for evidences [TBT] +Home.Evidences.SkippedFoldersOnRecursiveEvidenceFindAlertTitle=Skipped Folders [TBT] +Home.Configurable.Enable=Enable [TBT] +Home.Configurable.Disable=Disable [TBT] \ No newline at end of file diff --git a/iped-app/resources/localization/iped-desktop-messages_es_AR.properties b/iped-app/resources/localization/iped-desktop-messages_es_AR.properties index 51ffee2b71..c551a8ff98 100644 --- a/iped-app/resources/localization/iped-desktop-messages_es_AR.properties +++ b/iped-app/resources/localization/iped-desktop-messages_es_AR.properties @@ -78,6 +78,65 @@ BookmarksManager.AlreadyExists=¡El nombre del marcador ya existe! BookmarksTreeModel.NoBookmarks=[Sin marcadores] BookmarksTreeModel.RootName=Marcadores CategoryTreeModel.RootName=Categorías +Case.New=New[TBT] +Case.NewCase=New Case[TBT] +Case.Open=Open[TBT] +Case.OpenCase=Open Case[TBT] +Case.Options=Options[TBT] +Case.ProcessingOptions=Processing Options[TBT] +Case.CaseName=Name[TBT] +Case.CaseOutput=Output Folder[TBT] +Case.CaseChoose=Choose...[TBT] +Case.NonEmptyDirectoryAlert=The "{0}" directory is not empty. The "{1}" directory will be created. Do you wish to continue?[TBT] +Case.DatasourceType=Datasource Type[TBT] +Case.DatasourceInput=Datasource Input[TBT] +Case.DataSourceName=Datasource Name[TBT] +Case.DataSourceType=Type[TBT] +Case.PersonId=Person Id[TBT] +Case.BusinessId=Business Id[TBT] +Case.PersonIdMask= +Case.BusinessIdMask= +Case.AddDatasource=Add Datasource[TBT] +Case.RemoveDatasource=Remove Datasource[TBT] +Case.AddInput=Add Input[TBT] +Case.RemoveFile=Remove[TBT] +Case.CaseSaveError=An error occurred while saving the case: {0}[TBT] +Case.CaseLoadError=An error occurred while loading the case: {0}[TBT] +Case.CaseFile=Iped Case Files[TBT] +Case.SaveCase=Save[TBT] +Case.Cancel=Cancel[TBT] +Case.enableLedDie=Enable LED DIE[TBT] +Case.exportFileProps=Export File Properties[TBT] +Case.enableLanguageDetect=Enable Language Detection[TBT] +Case.enableRegexSearch=Enable Regex Search[TBT] +Case.enableNamedEntityRecogniton=Enable Entity Recognition[TBT] +Case.enableGraphGeneration=Enable Graph Generation[TBT] +Case.indexUnknownFiles=Index Unknown Files[TBT] +Case.addUnallocated=Process Unallocated[TBT] +Case.enableOCR=Enable OCR[TBT] +Case.enableLedDieHelp=Enables nudity detection.[TBT] +Case.exportFilePropsHelp=Exports the properties of all files to "Lista de Arquvivos.csv".[TBT] +Case.enableLanguageDetectHelp=Enables the detection of more than 70 languages.[TBT] +Case.enableRegexSearchHelp=Search the extracted text for regular expressions.[TBT] +Case.enableNamedEntityRecognitonHelp=Enables EXPERIMENTAL named entities detection feature. Additional configuration is necessary.[TBT] +Case.enableGraphGenerationHelp=Enables EXPERIMENTAL graph generation feature. Depends on regex search.[TBT] +Case.indexUnknownFilesHelp=Indexes unknown files as binaries, page files, unallocated, etc.[TBT] +Case.addUnallocatedHelp=Adds and processes unallocated areas via sleuthkit.[TBT] +Case.enableOCRHelp=Enables OCR at images and PDFs. May increase the processing time.[TBT] +Case.Yes=Yes[TBT] +Case.No=No[TBT] +Case.ProcessCase=Process[TBT] +Case.OptionsSaved=Options saved to file {0}.[TBT] +Case.OptionsSaveError==An error occurred while saving: {0}[TBT] +Case.PERSON=Person[TBT] +Case.BUSINESS=Business[TBT] +Case.GENERIC=Generic[TBT] +Case.PersonIdRegex= +Case.BusinessIdRegex= +Case.Profile=Profile[TBT] +Case.ProfileHelp=Processing profile selection.[TBT] +CategoryTreeModel.RootName=Categories[TBT] +CategoryTreeModel.Uncategorizables=Uncategorized[TBT] ColumnsManager.Advanced=Avanzado ColumnsManager.All=Todo ColumnsManager.Audio=Audio @@ -162,7 +221,7 @@ GraphAnalysis.Search=Buscar GraphAnalysis.Add=Añadir GraphAnalysis.Cancel=Cancelar GraphAnalysis.Export=Exportar -GraphAnalysis.Id +GraphAnalysis.Id=Id GraphAnalysis.Type=Tipo GraphAnalysis.Quantity=Cantidad GraphAnalysis.Property=Propiedad @@ -441,4 +500,159 @@ FieldValuePopupMenu.LessThan=Filter less than...(TBT) FieldValuePopupMenu.Equals=Equals to...(TBT) FieldValuePopupMenu.StartsWith=Starts with...(TBT) FieldValuePopupMenu.Clear=Clear(TBT) -FieldValuePopupMenu.Filter=Filter(TBT) \ No newline at end of file +FieldValuePopupMenu.Filter=Filter(TBT) +Home.StartNewCase=START NEW CASE [TBT] +Home.OpenCase=OPEN CASE [TBT] +Home.Config=CONFIGURATIONS [TBT] +Home.LocalEnviromentConfiguration=Local environment configuration [TBT] +Home.DefaultThreadValue=Set default thread value [TBT] +Home.ChooseDefaultIndexTempFolder=Choose default index temp folder [TBT] +Home.DefaultIndexTempToolTip=Set "Default" as Index Temp value (Default is your O.S. default temp path) [TBT] +Home.Language=Language [TBT] +Home.NumberOfThreads=Number of Threads [TBT] +Home.TempFolder=Temporary directory [TBT] +Home.HashDatabase=HashDB directory [TBT] +Home.TSKJar=TSK Jar Directory [TBT] +Home.TSKJarDialogTtitle=Choose TSK JAR file [TBT] +Home.OptionalPluginsPath=Optional plugins directory [TBT] +Home.OptPluginDialogTtitle=Choose optional plugins directory [TBT] +Home.IndexTempOnSSDLabel=Check this option if the "Temp`s Directory" is on an SSD device [TBT] +Home.InformHashDBFile=Inform the HashDB File [TBT] +Home.Save=Save [TBT] +Home.Cancel=Cancel [TBT] +Home.Next=Next [TBT] +Home.Back=Back [TBT] +Home.Select=Select [TBT] +Home.Active=Active [TBT] +Home.Inactive=Inactive [TBT] +Home.LanguagePtBR=Brazilian portuguese [TBT] +Home.LanguageEN=English [TBT] +Home.LanguageIT=Italian [TBT] +Home.LanguageDE=German [TBT] +Home.LanguageEsAr=Argentine Spanish [TBT] +Home.LanguageChangeMessage=You have selected a different language. Restart the application to apply the selected language. [TBT] +Home.LanguageChangeTitle=Language modification [TBT] +Home.CaseInformation=Case Information [TBT] +Home.CaseInformationTollTip=Case Detail [TBT] +Home.Evidences=Evidences [TBT] +Home.EvidencesToolTip=List of evidence to be processed [TBT] +Home.ProcessOptions=Process options [TBT] +Home.ProcessOptionsToolTip=Process task selection page [TBT] +Home.ProcessingTab=Processing [TBT] +Home.ProcessingTabTooltip=Processing evolution watch [TBT] +Home.NewCase.CaseOutput=*Case output [TBT] +Home.NewCase.ChooseCaseOutput=Choose case output [TBT] +Home.NewCase.IsCaseOutputOnSSD=Is case output on a SSD device? [TBT] +Home.NewCase.IsCaseOutputOnSSDToolTip=Enable if case output is on SSD. If enabled, index is created directly in case folder, not in indexTemp, so you will need less free space in temp folder. [TBT] +Home.NewCase.CaseOutputRequired=Case output is required [TBT] +Home.NewCase.CaseOutputRequiredTitle=Case output [TBT] +Home.NewCase.CaseOutputPermission=Read and write permission is required on the case output folder. [TBT] +Home.NewCase.CaseOutputPermissionTitle=Case output folder [TBT] +Home.NewCase.CaseOutPutOptionsRequired=You need to select an option for the case output folder. [TBT] +Home.NewCase.SaveCaseData=Save case data [TBT] +Home.NewCase.LoadCaseData=Load case data [TBT] +Home.NewCase.ChooseCaseInfoFileOutput=Choose case info file output [TBT] +Home.NewCase.ChooseCaseInfoFile=Choose case info file source [TBT] +Home.ExistentCaseAlert=A case already exists in the specified case output folder. Choose an option below or select other case output folder: [TBT] +Home.AppendExistentCase=Append - Append this case to the existing one [TBT] +Home.ContinueExistentCase=Continue - Continue the existing process [TBT] +Home.RestartExistentCase=Restart - Restart the existing process [TBT] +Home.Evidences.AddFolder=Add folder [TBT] +Home.Evidences.AddFile=Add file [TBT] +Home.Evidences.AddImagesRecursively=Add images recursively [TBT] +Home.Evidences.AddDisk=Add disk [TBT] +Home.Evidences.SelectFolder=Select folder [TBT] +Home.Evidences.SelectFile=Select file [TBT] +Home.Evidences.AddFileTitle=Add file [TBT] +Home.Evidences.ChooseSourceFolder=Select search root folder [TBT] +Home.Evidences.ImageSearchError=Image search error [TBT] +Home.Evidences.PathMustBeDirectory=Path must be a directory. [TBT] +Home.Evidences.Title=Evidences [TBT] +Home.Evidences.Table.FileName=File name [TBT] +Home.Evidences.Table.Alias=Alias [TBT] +Home.Evidences.Table.Path=Path [TBT] +Home.Evidences.Table.Options=Options [TBT] +Home.Evidences.DialogTitle=Evidences details [TBT] +Home.Evidences.Dialog.FileName=File name: [TBT] +Home.Evidences.Dialog.Path=File Path: [TBT] +Home.Evidences.Dialog.Alias=Alias: [TBT] +Home.Evidences.Dialog.EvidenceDesc=Evidence description: [TBT] +Home.Evidences.Dialog.Password=Password (APFS Image): [TBT] +Home.Evidences.Dialog.TimeZone=TimeZone (FAT FS): [TBT] +Home.Evidences.Dialog.BlockSize=Block size (0 = default): [TBT] +Home.Evidences.DisksDialog.Title=Choose the disk to be processed [TBT] +Home.Evidences.DisksDialog.Name=Name [TBT] +Home.Evidences.DisksDialog.Model=Model [TBT] +Home.Evidences.DisksDialog.Size=Size [TBT] +Home.Evidences.DisksDialog.Serial=Serial [TBT] +Home.Evidences.DisksDialog.Select=Select [TBT] +Home.Evidences.DisksDialog.NotAdmin=You must be admin to process physical drives[TBT] +Home.Evidences.NoEvidencesAlert=You need to choose at least one evidence to continue [TBT] +Home.Evidences.NoEvidencesAlertTitle=No evidences selected [TBT] +Home.ProcOptions.Title=Process options [TBT] +Home.ProcOptions.ExecProfile=Execution profile: [TBT] +Home.ProcOptions.NewProfile=New profile name: [TBT] +Home.ProcOptions.ButtonStarExecTooltip=Save or cancel profile edition before continue. [TBT] +Home.ProcOptions.CreateNewProfile=Create new profile [TBT] +Home.ProcOptions.AddScriptTask=Add script task [TBT] +Home.ProcOptions.StartProcessing=Start processing [TBT] +Home.ProcOptions.Table.Options=Options [TBT] +Home.ProcOptions.ScriptAlreadyExists=Script destination folder already has a file with this name. Please change the name of the source script first. [TBT] +Home.ProcessManager.StartingProcess=Hang on, we are starting your processing.. [TBT] +Home.ProcessManager.ProcessFailed=IPED execution failed.. [TBT] +Home.ProcessManager.ProcessRunning=IPED is processing.. [TBT] +Home.ProcessManager.ProcessFinished=Process finished successfully!! [TBT] +Home.ProcessManager.BackToCaseInfo=Back to case info [TBT] +Home.ProcessManager.ShowTerminalLog=View Processing Log [TBT] +Home.ProcessManager.OpenCase=Open case [TBT] +Home.ProcessManager.OpenCaseMsg=Wait... [TBT] +Home.ProcessManager.TerminalLog=Terminal log [TBT] +Home.ProcessManager.ExitApplication=Exit application [TBT] +Home.OpenCase.OpenCase=Open Case(s) [TBT] +Home.OpenCase.AddCaseToList=Add a case to the list [TBT] +Home.OpenCase.RemoveCaseFromList=Remove the case from list [TBT] +Home.OpenCase.SelectCaseFolder=Select case folder [TBT] +Home.OpenCase.OpenAllCasesInTheList=Open all cases in the list [TBT] +Home.OpenCase.EmptyCaseMessage=You need add at least one case to list [TBT] +Home.OpenCase.EmptyCaseMessageTitle=Empty case list [TBT] +Home.OpenCase.CaseLocation=Case location [TBT] +Home.OpenCase.CaseTableHeader=CASE LIST [TBT] +Home.IPEDMimeSeachList.showTikaMimeTypes=Show Tika mime types [TBT] +Home.configurables.AdvancedPanelLabel=Advanced [TBT] +Home.configurables.BasicPanelLabel=Basic configuration [TBT] +Home.configurables.BasicCarverPanelLabel=Carvers list [TBT] +Home.configurables.BasicParsersPanelLabel=Parsers list [TBT] +ScriptEditPanel.File=File:[TBT] +ScriptEditPanel.SelectTemplateLabel=Select Template:[TBT] +ScriptEditPanel.StartEditing=Start editing[TBT] +ScriptEditPanel.Preview=Preview[TBT] +ScriptEditPanel.ImportScript.tooltip=Load script from file[TBT] +ScriptEditPanel.ImportScript=Import script[TBT] +iped.app.home.configurables.ParsersConfigurablePanel.EmptyNameError=Parser name field empty. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.EmptyCommandError=Command field empty. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.EmptyMimeTypeError=Mime-types field empty. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.InvalidMimeTypeError=Invalid mimetype [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.UnregisteredMimeTypeError="Mime type specified is not registered [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.EmptyCharsetError=Charset field empty. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.InvalidFirstLinesToSkipError=Invalid value informed as number of first lines to skip. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.InvalidCharsetError=Invalid charset. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.EditVetoError=Edition of external parser in course. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.CreateExternalParser=Create external parser [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.NewExternalParserPanel=New external Parser [TBT] +ScriptEditPanel.scriptScopeWarn=The script file is saved in shared script folder, affecting all profile configurations. Do you want to continue editing? [TBT] +ReportDialog.InvestigatedNames=Investigated Name [TBT] +ReportDialog.organizationName=Organization Name [TBT] +ReportDialog.contact=Contact [TBT] +ReportDialog.caseNotes=Case notes [TBT] +Home.OpenCase.InavlidCasePath=Invalid Case Path[TBT] +Home.OpenCase.NoSearchApp=IPED-SearchApp not found [TBT] +Home.OpenCase.CaseNotFinished=The case process is not finished [TBT] +Home.OpenCase.CaseV3NotSupported=Cases from version 3 are not supported[TBT] +Home.NewCase.OpenCaseFileDialogTitle=Overwrite information? [TBT] +Home.NewCase.OpenCaseFileDialogMessage=Do you want to overwrite existing information with information from the file? [TBT] +Home.ProcessManager.ExistentCaseAlertMessage=A case already exists in the directory in the case destination folder. What do you wanna do? [TBT] +Home.ProcessManager.ExistentCaseAlertTitle=Existing case [TBT] +Home.Evidences.SkippedFoldersOnRecursiveEvidenceFind=Some folders were inaccessible and skipped when searching for evidences [TBT] +Home.Evidences.SkippedFoldersOnRecursiveEvidenceFindAlertTitle=Skipped Folders [TBT] +Home.Configurable.Enable=Enable [TBT] +Home.Configurable.Disable=Disable [TBT] \ No newline at end of file diff --git a/iped-app/resources/localization/iped-desktop-messages_fr_FR.properties b/iped-app/resources/localization/iped-desktop-messages_fr_FR.properties index 7ed824bdc6..985bf70491 100644 --- a/iped-app/resources/localization/iped-desktop-messages_fr_FR.properties +++ b/iped-app/resources/localization/iped-desktop-messages_fr_FR.properties @@ -78,6 +78,65 @@ BookmarksManager.AlreadyExists=Nom du favori existe déjà \! BookmarksTreeModel.NoBookmarks=[Aucun favori] BookmarksTreeModel.RootName=Favoris CategoryTreeModel.RootName=Catégories +Case.New=New[TBT] +Case.NewCase=New Case[TBT] +Case.Open=Open[TBT] +Case.OpenCase=Open Case[TBT] +Case.Options=Options[TBT] +Case.ProcessingOptions=Processing Options[TBT] +Case.CaseName=Name[TBT] +Case.CaseOutput=Output Folder[TBT] +Case.CaseChoose=Choose...[TBT] +Case.NonEmptyDirectoryAlert=The "{0}" directory is not empty. The "{1}" directory will be created. Do you wish to continue?[TBT] +Case.DatasourceType=Datasource Type[TBT] +Case.DatasourceInput=Datasource Input[TBT] +Case.DataSourceName=Datasource Name[TBT] +Case.DataSourceType=Type[TBT] +Case.PersonId=Person Id[TBT] +Case.BusinessId=Business Id[TBT] +Case.PersonIdMask= +Case.BusinessIdMask= +Case.AddDatasource=Add Datasource[TBT] +Case.RemoveDatasource=Remove Datasource[TBT] +Case.AddInput=Add Input[TBT] +Case.RemoveFile=Remove[TBT] +Case.CaseSaveError=An error occurred while saving the case: {0}[TBT] +Case.CaseLoadError=An error occurred while loading the case: {0}[TBT] +Case.CaseFile=Iped Case Files[TBT] +Case.SaveCase=Save[TBT] +Case.Cancel=Cancel[TBT] +Case.enableLedDie=Enable LED DIE[TBT] +Case.exportFileProps=Export File Properties[TBT] +Case.enableLanguageDetect=Enable Language Detection[TBT] +Case.enableRegexSearch=Enable Regex Search[TBT] +Case.enableNamedEntityRecogniton=Enable Entity Recognition[TBT] +Case.enableGraphGeneration=Enable Graph Generation[TBT] +Case.indexUnknownFiles=Index Unknown Files[TBT] +Case.addUnallocated=Process Unallocated[TBT] +Case.enableOCR=Enable OCR[TBT] +Case.enableLedDieHelp=Enables nudity detection.[TBT] +Case.exportFilePropsHelp=Exports the properties of all files to "Lista de Arquvivos.csv".[TBT] +Case.enableLanguageDetectHelp=Enables the detection of more than 70 languages.[TBT] +Case.enableRegexSearchHelp=Search the extracted text for regular expressions.[TBT] +Case.enableNamedEntityRecognitonHelp=Enables EXPERIMENTAL named entities detection feature. Additional configuration is necessary.[TBT] +Case.enableGraphGenerationHelp=Enables EXPERIMENTAL graph generation feature. Depends on regex search.[TBT] +Case.indexUnknownFilesHelp=Indexes unknown files as binaries, page files, unallocated, etc.[TBT] +Case.addUnallocatedHelp=Adds and processes unallocated areas via sleuthkit.[TBT] +Case.enableOCRHelp=Enables OCR at images and PDFs. May increase the processing time.[TBT] +Case.Yes=Yes[TBT] +Case.No=No[TBT] +Case.ProcessCase=Process[TBT] +Case.OptionsSaved=Options saved to file {0}.[TBT] +Case.OptionsSaveError==An error occurred while saving: {0}[TBT] +Case.PERSON=Person[TBT] +Case.BUSINESS=Business[TBT] +Case.GENERIC=Generic[TBT] +Case.PersonIdRegex= +Case.BusinessIdRegex= +Case.Profile=Profile[TBT] +Case.ProfileHelp=Processing profile selection.[TBT] +CategoryTreeModel.RootName=Categories[TBT] +CategoryTreeModel.Uncategorizables=Uncategorized[TBT] ColumnsManager.Advanced=Avancées ColumnsManager.All=Toutes ColumnsManager.Audio=Audio @@ -442,3 +501,158 @@ FieldValuePopupMenu.Equals=Égal à... FieldValuePopupMenu.StartsWith=Commençant par... FieldValuePopupMenu.Clear=Efacer FieldValuePopupMenu.Filter=Filtre +Home.StartNewCase=START NEW CASE [TBT] +Home.OpenCase=OPEN CASE [TBT] +Home.Config=CONFIGURATIONS [TBT] +Home.LocalEnviromentConfiguration=Local environment configuration [TBT] +Home.DefaultThreadValue=Set default thread value [TBT] +Home.ChooseDefaultIndexTempFolder=Choose default index temp folder [TBT] +Home.DefaultIndexTempToolTip=Set "Default" as Index Temp value (Default is your O.S. default temp path) [TBT] +Home.Language=Language [TBT] +Home.NumberOfThreads=Number of Threads [TBT] +Home.TempFolder=Temporary directory [TBT] +Home.HashDatabase=HashDB directory [TBT] +Home.TSKJar=TSK Jar Directory [TBT] +Home.TSKJarDialogTtitle=Choose TSK JAR file [TBT] +Home.OptionalPluginsPath=Optional plugins directory [TBT] +Home.OptPluginDialogTtitle=Choose optional plugins directory [TBT] +Home.IndexTempOnSSDLabel=Check this option if the "Temp`s Directory" is on an SSD device [TBT] +Home.InformHashDBFile=Inform the HashDB File [TBT] +Home.Save=Save [TBT] +Home.Cancel=Cancel [TBT] +Home.Next=Next [TBT] +Home.Back=Back [TBT] +Home.Select=Select [TBT] +Home.Active=Active [TBT] +Home.Inactive=Inactive [TBT] +Home.LanguagePtBR=Brazilian portuguese [TBT] +Home.LanguageEN=English [TBT] +Home.LanguageIT=Italian [TBT] +Home.LanguageDE=German [TBT] +Home.LanguageEsAr=Argentine Spanish [TBT] +Home.LanguageChangeMessage=You have selected a different language. Restart the application to apply the selected language. [TBT] +Home.LanguageChangeTitle=Language modification [TBT] +Home.CaseInformation=Case Information [TBT] +Home.CaseInformationTollTip=Case Detail [TBT] +Home.Evidences=Evidences [TBT] +Home.EvidencesToolTip=List of evidence to be processed [TBT] +Home.ProcessOptions=Process options [TBT] +Home.ProcessOptionsToolTip=Process task selection page [TBT] +Home.ProcessingTab=Processing [TBT] +Home.ProcessingTabTooltip=Processing evolution watch [TBT] +Home.NewCase.CaseOutput=*Case output [TBT] +Home.NewCase.ChooseCaseOutput=Choose case output [TBT] +Home.NewCase.IsCaseOutputOnSSD=Is case output on a SSD device? [TBT] +Home.NewCase.IsCaseOutputOnSSDToolTip=Enable if case output is on SSD. If enabled, index is created directly in case folder, not in indexTemp, so you will need less free space in temp folder. [TBT] +Home.NewCase.CaseOutputRequired=Case output is required [TBT] +Home.NewCase.CaseOutputRequiredTitle=Case output [TBT] +Home.NewCase.CaseOutputPermission=Read and write permission is required on the case output folder. [TBT] +Home.NewCase.CaseOutputPermissionTitle=Case output folder [TBT] +Home.NewCase.CaseOutPutOptionsRequired=You need to select an option for the case output folder. [TBT] +Home.NewCase.SaveCaseData=Save case data [TBT] +Home.NewCase.LoadCaseData=Load case data [TBT] +Home.NewCase.ChooseCaseInfoFileOutput=Choose case info file output [TBT] +Home.NewCase.ChooseCaseInfoFile=Choose case info file source [TBT] +Home.ExistentCaseAlert=A case already exists in the specified case output folder. Choose an option below or select other case output folder: [TBT] +Home.AppendExistentCase=Append - Append this case to the existing one [TBT] +Home.ContinueExistentCase=Continue - Continue the existing process [TBT] +Home.RestartExistentCase=Restart - Restart the existing process [TBT] +Home.Evidences.AddFolder=Add folder [TBT] +Home.Evidences.AddFile=Add file [TBT] +Home.Evidences.AddImagesRecursively=Add images recursively [TBT] +Home.Evidences.AddDisk=Add disk [TBT] +Home.Evidences.SelectFolder=Select folder [TBT] +Home.Evidences.SelectFile=Select file [TBT] +Home.Evidences.AddFileTitle=Add file [TBT] +Home.Evidences.ChooseSourceFolder=Select search root folder [TBT] +Home.Evidences.ImageSearchError=Image search error [TBT] +Home.Evidences.PathMustBeDirectory=Path must be a directory. [TBT] +Home.Evidences.Title=Evidences [TBT] +Home.Evidences.Table.FileName=File name [TBT] +Home.Evidences.Table.Alias=Alias [TBT] +Home.Evidences.Table.Path=Path [TBT] +Home.Evidences.Table.Options=Options [TBT] +Home.Evidences.DialogTitle=Evidences details [TBT] +Home.Evidences.Dialog.FileName=File name: [TBT] +Home.Evidences.Dialog.Path=File Path: [TBT] +Home.Evidences.Dialog.Alias=Alias: [TBT] +Home.Evidences.Dialog.EvidenceDesc=Evidence description: [TBT] +Home.Evidences.Dialog.Password=Password (APFS Image): [TBT] +Home.Evidences.Dialog.TimeZone=TimeZone (FAT FS): [TBT] +Home.Evidences.Dialog.BlockSize=Block size (0 = default): [TBT] +Home.Evidences.DisksDialog.Title=Choose the disk to be processed [TBT] +Home.Evidences.DisksDialog.Name=Name [TBT] +Home.Evidences.DisksDialog.Model=Model [TBT] +Home.Evidences.DisksDialog.Size=Size [TBT] +Home.Evidences.DisksDialog.Serial=Serial [TBT] +Home.Evidences.DisksDialog.Select=Select [TBT] +Home.Evidences.DisksDialog.NotAdmin=You must be admin to process physical drives[TBT] +Home.Evidences.NoEvidencesAlert=You need to choose at least one evidence to continue [TBT] +Home.Evidences.NoEvidencesAlertTitle=No evidences selected [TBT] +Home.ProcOptions.Title=Process options [TBT] +Home.ProcOptions.ExecProfile=Execution profile: [TBT] +Home.ProcOptions.NewProfile=New profile name: [TBT] +Home.ProcOptions.ButtonStarExecTooltip=Save or cancel profile edition before continue. [TBT] +Home.ProcOptions.CreateNewProfile=Create new profile [TBT] +Home.ProcOptions.AddScriptTask=Add script task [TBT] +Home.ProcOptions.StartProcessing=Start processing [TBT] +Home.ProcOptions.Table.Options=Options [TBT] +Home.ProcOptions.ScriptAlreadyExists=Script destination folder already has a file with this name. Please change the name of the source script first. [TBT] +Home.ProcessManager.StartingProcess=Hang on, we are starting your processing.. [TBT] +Home.ProcessManager.ProcessFailed=IPED execution failed.. [TBT] +Home.ProcessManager.ProcessRunning=IPED is processing.. [TBT] +Home.ProcessManager.ProcessFinished=Process finished successfully!! [TBT] +Home.ProcessManager.BackToCaseInfo=Back to case info [TBT] +Home.ProcessManager.ShowTerminalLog=View Processing Log [TBT] +Home.ProcessManager.OpenCase=Open case [TBT] +Home.ProcessManager.OpenCaseMsg=Wait... [TBT] +Home.ProcessManager.TerminalLog=Terminal log [TBT] +Home.ProcessManager.ExitApplication=Exit application [TBT] +Home.OpenCase.OpenCase=Open Case(s) [TBT] +Home.OpenCase.AddCaseToList=Add a case to the list [TBT] +Home.OpenCase.RemoveCaseFromList=Remove the case from list [TBT] +Home.OpenCase.SelectCaseFolder=Select case folder [TBT] +Home.OpenCase.OpenAllCasesInTheList=Open all cases in the list [TBT] +Home.OpenCase.EmptyCaseMessage=You need add at least one case to list [TBT] +Home.OpenCase.EmptyCaseMessageTitle=Empty case list [TBT] +Home.OpenCase.CaseLocation=Case location [TBT] +Home.OpenCase.CaseTableHeader=CASE LIST [TBT] +Home.IPEDMimeSeachList.showTikaMimeTypes=Show Tika mime types [TBT] +Home.configurables.AdvancedPanelLabel=Advanced [TBT] +Home.configurables.BasicPanelLabel=Basic configuration [TBT] +Home.configurables.BasicCarverPanelLabel=Carvers list [TBT] +Home.configurables.BasicParsersPanelLabel=Parsers list [TBT] +ScriptEditPanel.File=File:[TBT] +ScriptEditPanel.SelectTemplateLabel=Select Template:[TBT] +ScriptEditPanel.StartEditing=Start editing[TBT] +ScriptEditPanel.Preview=Preview[TBT] +ScriptEditPanel.ImportScript.tooltip=Load script from file[TBT] +ScriptEditPanel.ImportScript=Import script[TBT] +iped.app.home.configurables.ParsersConfigurablePanel.EmptyNameError=Parser name field empty. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.EmptyCommandError=Command field empty. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.EmptyMimeTypeError=Mime-types field empty. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.InvalidMimeTypeError=Invalid mimetype [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.UnregisteredMimeTypeError="Mime type specified is not registered [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.EmptyCharsetError=Charset field empty. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.InvalidFirstLinesToSkipError=Invalid value informed as number of first lines to skip. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.InvalidCharsetError=Invalid charset. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.EditVetoError=Edition of external parser in course. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.CreateExternalParser=Create external parser [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.NewExternalParserPanel=New external Pars [TBT]er +ScriptEditPanel.scriptScopeWarn=The script file is saved in shared script folder, affecting all profile configurations. Do you want to continue editing? [TBT] +ReportDialog.InvestigatedNames=Investigated Name [TBT] +ReportDialog.organizationName=Organization Name [TBT] +ReportDialog.contact=Contact [TBT] +ReportDialog.caseNotes=Case notes [TBT] +Home.OpenCase.InavlidCasePath=Invalid Case Path[TBT] +Home.OpenCase.NoSearchApp=IPED-SearchApp not found [TBT] +Home.OpenCase.CaseNotFinished=The case process is not finished [TBT] +Home.OpenCase.CaseV3NotSupported=Cases from version 3 are not supported[TBT] +Home.NewCase.OpenCaseFileDialogTitle=Overwrite information? [TBT] +Home.NewCase.OpenCaseFileDialogMessage=Do you want to overwrite existing information with information from the file? [TBT] +Home.ProcessManager.ExistentCaseAlertMessage=A case already exists in the directory in the case destination folder. What do you wanna do? [TBT] +Home.ProcessManager.ExistentCaseAlertTitle=Existing case [TBT] +Home.Evidences.SkippedFoldersOnRecursiveEvidenceFind=Some folders were inaccessible and skipped when searching for evidences [TBT] +Home.Evidences.SkippedFoldersOnRecursiveEvidenceFindAlertTitle=Skipped Folders [TBT] +Home.Configurable.Enable=Enable [TBT] +Home.Configurable.Disable=Disable [TBT] \ No newline at end of file diff --git a/iped-app/resources/localization/iped-desktop-messages_it_IT.properties b/iped-app/resources/localization/iped-desktop-messages_it_IT.properties index a0747a92a6..30159e1048 100644 --- a/iped-app/resources/localization/iped-desktop-messages_it_IT.properties +++ b/iped-app/resources/localization/iped-desktop-messages_it_IT.properties @@ -29,7 +29,8 @@ AppLazyInitializer.errorTitle=Errore di inizializzazione AppListener.NoHits=Nessun risultato AppListener.UncheckAll=Confermi di voler deselezionare tutte le voci? AppListener.UncheckAll.Title=Conferma -AppMain.NoCasesFile=File elenco casi non trovato: +AppMain.error.Title=Errore di inizializzazione +AppMain.NoCasesFile=File elenco casi non trovato: AppMain.warn.Title=Avviso di inizializzazione BookmarksController.HistoryDelimiter=-----------------------Storia----------------------- BookmarksController.LoadError=Errore nel caricamento dei segnalibri\! @@ -77,7 +78,65 @@ BookmarksManager.UpdateTooltip=Aggiorna commento BookmarksManager.AlreadyExists=Il nome del segnalibro esiste già! BookmarksTreeModel.NoBookmarks=[Nessun segnalibro] BookmarksTreeModel.RootName=Segnalibri +Case.New=Nuovo +Case.NewCase=Nuovo Caso +Case.Open=Apri +Case.OpenCase=Apri Caso +Case.Options=Opzioni +Case.ProcessingOptions=Opzioni di elaborazione +Case.CaseName=Nome +Case.CaseOutput=Cartella di destinazione +Case.CaseChoose=Scegli... +Case.NonEmptyDirectoryAlert=la cartella "{0}" non è vuota. La cartella "{1}" sarà creata. Vuoi continuare? +Case.DatasourceType=Tipo Sorgente Dati +Case.DatasourceInput=Ingresso Sorgente Dati +Case.DataSourceName=Nome Sorgente Dati +Case.DataSourceType=Tipo +Case.PersonId=ID Persona +Case.BusinessId=ID Azienda +Case.PersonIdMask=###.###.###-## +Case.BusinessIdMask=##.###.###/####-## +Case.AddDatasource=Aggiungi Sorgente Dati +Case.RemoveDatasource=Rimuovi Sorgente +Case.AddInput=Aggiungi Input +Case.RemoveFile=Rimuovi +Case.CaseSaveError=Si è verificato un errore durante il salvataggio del Caso: {0} +Case.CaseLoadError=Si è verificato un errore durante il caricamento del Caso: {0} +Case.CaseFile=Archivio Casi IPED +Case.SaveCase=Salva +Case.Cancel=Cancella +Case.enableLedDie=Abilita LED DIE +Case.exportFileProps=Esporta Proprietà File +Case.enableLanguageDetect=Abilita il rilevamento della lingua +Case.enableRegexSearch=Abilita ricerca RegEx +Case.enableNamedEntityRecogniton=Abilita riconoscimento entità +Case.enableGraphGeneration=Abilita generazione grafo +Case.indexUnknownFiles=Indicizza file sconosciuti +Case.addUnallocated=Processa spazio non allocato +Case.enableOCR=Abilita OCR +Case.enableLedDieHelp=Abilita rilevamento nudità. +Case.exportFilePropsHelp=Esporta le proprietà di tutti i file in "ElencoFile.csv". +Case.enableLanguageDetectHelp=Abilita il rilevamento di più di 70 lingue. +Case.enableRegexSearchHelp=Cerca le espressioni RegEx nel testo estratto. +Case.enableNamedEntityRecognitonHelp=Abilita la funzione SPERIMENTALE di rilevamento delle entità nominate. È necessaria un''ulteriore configurazione. +Case.enableGraphGenerationHelp=Abilita la funzione SPERIMENTALE di generazione dei grafici. Dipende dalla ricerca RegEx. +Case.indexUnknownFilesHelp=Indicizza file sconosciuti come binari, page file, non allocati, ecc. +Case.addUnallocatedHelp=Aggiunge e processa aree non allocate tramite Sleuthkit. +Case.enableOCRHelp=Abilita OCR su immagini e PDF. Può aumentare il tempo di elaborazione. +Case.Yes=Sì +Case.No=No +Case.ProcessCase=Elabora +Case.OptionsSaved=Opzioni salvate nel file {0}. +Case.OptionsSaveError==Si è verificato un errore durante il salvataggio: {0} +Case.PERSON=Persona +Case.BUSINESS=Azienda +Case.GENERIC=Generico +Case.PersonIdRegex=RegEx ID Persona +Case.BusinessIdRegex=RegEx ID Azienda +Case.Profile=Profilo +Case.ProfileHelp=Elabora profilo selezionato. CategoryTreeModel.RootName=Categorie +CategoryTreeModel.Uncategorizables=Uncategorized[TBT] ColumnsManager.Advanced=Avanzate ColumnsManager.All=Tutto ColumnsManager.Audio=Audio @@ -102,19 +161,19 @@ ColumnsManager.AutoManageCols=Gestione automatica delle colonne (più lento) ColumnsManager.LoadingCols=Caricamento colonne utilizzate... ColumnsManager.Filter=[Tipo di filtro] ColumnsManager.WindowsEvt=Eventi Windows -CopyProperties.Copying=Copia +CopyProperties.Copying=Copia CopyProperties.CSVDateFormat=dd/MM/yyyy HH:mm:ss z CopyProperties.CSVDelimiter=, -CopyProperties.from=\ di +CopyProperties.from=\ di DuplicatesTableModel.Duplicates=\ Duplicati -ExportFiles.Copying=Copia -ExportFiles.of=\ di -ExportFilesToZip.Copying=Copia -ExportFilesToZip.from=\ di +ExportFiles.Copying=Copia +ExportFiles.of=\ di +ExportFilesToZip.Copying=Copia +ExportFilesToZip.from=\ di ExportFileTree.Copied=Copiato ExportFileTree.ExportError=Errore nell''esportazione dei file. Controlla i permessi e lo spazio disponibile.\n -ExportFileTree.from=\ di -ExportIndexedTerms.Exported=Esportato +ExportFileTree.from=\ di +ExportIndexedTerms.Exported=Esportato ExportIndexedTerms.ofWords=\ di parole. ExportToZIP.DefaultName=FileEsportati.zip ExportToZIP.DefaultPath=/home/caine/DATI_ESPORTATI @@ -178,7 +237,7 @@ GraphAnalysis.Results=Trovato {0} risultati in {1}ms. GraphAnalysis.AdvancedSearch=Ricerca avanzata GraphAnalysis.AddToAnalysis=Aggiungi all''analisi GraphAnalysis.Execute=Esegui -GraphAnalysis.SearchLinks=Ricerca Collegamenti +GraphAnalysis.SearchLinks=Ricerca Collegamenti GraphAnalysis.Links=Collegamenti GraphAnalysis.Datasources=Sorgente dati GraphAnalysis.LinksSearching=Cerca Collegamenti... Trovato {0}. @@ -187,9 +246,9 @@ GraphAnalysis.MultiGraphError=Non è stato possibile creare il grafico del multi GraphAnalysis.MultiGraphOk=Grafico multi-caso creato. GraphAnalysis.InitialGraphMsg=Vista iniziale del grafico pronta. Include solo gli elementi più frequenti KeywordListImporter.BookmarkPrefix=Results of search for: [TBT] -KeywordListImporter.Msg.1=Importato -KeywordListImporter.Msg.2=\ parole chiave con risultati di -KeywordListImporter.SyntaxError=Errore di sintassi nelle seguenti espressioni: +KeywordListImporter.Msg.1=Importato +KeywordListImporter.Msg.2=\ parole chiave con risultati di +KeywordListImporter.SyntaxError=Errore di sintassi nelle seguenti espressioni: HashDialog.MD5Title=Hash MD5 del file ZIP esportato ImageSimilarity.ExternalError=Impossibile aprire l''immagine selezionata. ImageSimilarity.ExternalTitle=Immagine simile esterna @@ -254,7 +313,7 @@ MenuClass.SaveBookmarks=Salva Segnalibri MenuClass.UiZoom=Cambia lo zoom dell''interfaccia utente MenuClass.IconSize=Dimensione icona MenuClass.UnCheckHighlighted=Deseleziona elementi evidenziati -MenuClass.UnCheckRecursivelyHighlighted=Deseleziona gli elementi evidenziati e i sotto-elementi +MenuClass.UnCheckRecursivelyHighlighted=Deseleziona gli elementi evidenziati e i sotto-elementi MenuListener.ChatNotFound=Chat d''origine non trovata MenuListener.Cols=Colonne: MenuListener.ExportTree.Warn=Evidenzia 01 (un) nodo dell''albero come riferimento all''esportazione\! @@ -329,11 +388,11 @@ ResultTableRowSorter.Sorting=Ordinamento... RowComparator.SortCanceled=Ordinamento annullato. SearchStateFilter.BookmarksFile=File dei segnalibri SubitemTableModel.Subitens=\ Allegati/Sotto-elementi -TextParserListener.Found=Trovato +TextParserListener.Found=Trovato TextParserListener.hits=\ risultati TreeViewModel.RootName=Reperti UISearcher.Canceled=Ricerca annullata\! -UISearcher.Error.Msg=Errore di sintassi della ricerca: +UISearcher.Error.Msg=Errore di sintassi della ricerca: UISearcher.Error.Title=Errore UnsupportedIcon.Unavailable=Anteprima non supportata ViewerController.OfficeViewerUnSupported=Il viewer di Office non è più supportato in Java 32bit! Per favore installa Java 64bit. @@ -441,4 +500,159 @@ FieldValuePopupMenu.LessThan=Filter less than...(TBT) FieldValuePopupMenu.Equals=Equals to...(TBT) FieldValuePopupMenu.StartsWith=Starts with...(TBT) FieldValuePopupMenu.Clear=Clear(TBT) -FieldValuePopupMenu.Filter=Filter(TBT) \ No newline at end of file +FieldValuePopupMenu.Filter=Filter(TBT) +Home.StartNewCase=START NEW CASE [TBT] +Home.OpenCase=OPEN CASE [TBT] +Home.Config=CONFIGURATIONS [TBT] +Home.LocalEnviromentConfiguration=Local environment configuration [TBT] +Home.DefaultThreadValue=Set default thread value [TBT] +Home.ChooseDefaultIndexTempFolder=Choose default index temp folder [TBT] +Home.DefaultIndexTempToolTip=Set "Default" as Index Temp value (Default is your O.S. default temp path) [TBT] +Home.Language=Language [TBT] +Home.NumberOfThreads=Number of Threads [TBT] +Home.TempFolder=Temporary directory [TBT] +Home.HashDatabase=HashDB directory [TBT] +Home.TSKJar=TSK Jar Directory [TBT] +Home.TSKJarDialogTtitle=Choose TSK JAR file [TBT] +Home.OptionalPluginsPath=Optional plugins directory [TBT] +Home.OptPluginDialogTtitle=Choose optional plugins directory [TBT] +Home.IndexTempOnSSDLabel=Check this option if the "Temp`s Directory" is on an SSD device [TBT] +Home.InformHashDBFile=Inform the HashDB File [TBT] +Home.Save=Save [TBT] +Home.Cancel=Cancel [TBT] +Home.Next=Next [TBT] +Home.Back=Back [TBT] +Home.Select=Select [TBT] +Home.Active=Active [TBT] +Home.Inactive=Inactive [TBT] +Home.LanguagePtBR=Brazilian portuguese [TBT] +Home.LanguageEN=English [TBT] +Home.LanguageIT=Italian [TBT] +Home.LanguageDE=German [TBT] +Home.LanguageEsAr=Argentine Spanish [TBT] +Home.LanguageChangeMessage=You have selected a different language. Restart the application to apply the selected language. [TBT] +Home.LanguageChangeTitle=Language modification [TBT] +Home.CaseInformation=Case Information [TBT] +Home.CaseInformationTollTip=Case Detail [TBT] +Home.Evidences=Evidences [TBT] +Home.EvidencesToolTip=List of evidence to be processed [TBT] +Home.ProcessOptions=Process options [TBT] +Home.ProcessOptionsToolTip=Process task selection page [TBT] +Home.ProcessingTab=Processing [TBT] +Home.ProcessingTabTooltip=Processing evolution watch [TBT] +Home.NewCase.CaseOutput=*Case output [TBT] +Home.NewCase.ChooseCaseOutput=Choose case output [TBT] +Home.NewCase.IsCaseOutputOnSSD=Is case output on a SSD device? [TBT] +Home.NewCase.IsCaseOutputOnSSDToolTip=Enable if case output is on SSD. If enabled, index is created directly in case folder, not in indexTemp, so you will need less free space in temp folder. [TBT] +Home.NewCase.CaseOutputRequired=Case output is required [TBT] +Home.NewCase.CaseOutputRequiredTitle=Case output [TBT] +Home.NewCase.CaseOutputPermission=Read and write permission is required on the case output folder. [TBT] +Home.NewCase.CaseOutputPermissionTitle=Case output folder [TBT] +Home.NewCase.CaseOutPutOptionsRequired=You need to select an option for the case output folder. [TBT] +Home.NewCase.SaveCaseData=Save case data [TBT] +Home.NewCase.LoadCaseData=Load case data [TBT] +Home.NewCase.ChooseCaseInfoFileOutput=Choose case info file output [TBT] +Home.NewCase.ChooseCaseInfoFile=Choose case info file source [TBT] +Home.ExistentCaseAlert=A case already exists in the specified case output folder. Choose an option below or select other case output folder: [TBT] +Home.AppendExistentCase=Append - Append this case to the existing one [TBT] +Home.ContinueExistentCase=Continue - Continue the existing process [TBT] +Home.RestartExistentCase=Restart - Restart the existing process [TBT] +Home.Evidences.AddFolder=Add folder [TBT] +Home.Evidences.AddFile=Add file [TBT] +Home.Evidences.AddImagesRecursively=Add images recursively [TBT] +Home.Evidences.AddDisk=Add disk [TBT] +Home.Evidences.SelectFolder=Select folder [TBT] +Home.Evidences.SelectFile=Select file [TBT] +Home.Evidences.AddFileTitle=Add file [TBT] +Home.Evidences.ChooseSourceFolder=Select search root folder [TBT] +Home.Evidences.ImageSearchError=Image search error [TBT] +Home.Evidences.PathMustBeDirectory=Path must be a directory. [TBT] +Home.Evidences.Title=Evidences [TBT] +Home.Evidences.Table.FileName=File name [TBT] +Home.Evidences.Table.Alias=Alias [TBT] +Home.Evidences.Table.Path=Path [TBT] +Home.Evidences.Table.Options=Options [TBT] +Home.Evidences.DialogTitle=Evidences details [TBT] +Home.Evidences.Dialog.FileName=File name: [TBT] +Home.Evidences.Dialog.Path=File Path: [TBT] +Home.Evidences.Dialog.Alias=Alias: [TBT] +Home.Evidences.Dialog.EvidenceDesc=Evidence description: [TBT] +Home.Evidences.Dialog.Password=Password (APFS Image): [TBT] +Home.Evidences.Dialog.TimeZone=TimeZone (FAT FS): [TBT] +Home.Evidences.Dialog.BlockSize=Block size (0 = default): [TBT] +Home.Evidences.DisksDialog.Title=Choose the disk to be processed [TBT] +Home.Evidences.DisksDialog.Name=Name [TBT] +Home.Evidences.DisksDialog.Model=Model [TBT] +Home.Evidences.DisksDialog.Size=Size [TBT] +Home.Evidences.DisksDialog.Serial=Serial [TBT] +Home.Evidences.DisksDialog.Select=Select [TBT] +Home.Evidences.DisksDialog.NotAdmin=You must be admin to process physical drives[TBT] +Home.Evidences.NoEvidencesAlert=You need to choose at least one evidence to continue [TBT] +Home.Evidences.NoEvidencesAlertTitle=No evidences selected [TBT] +Home.ProcOptions.Title=Process options [TBT] +Home.ProcOptions.ExecProfile=Execution profile: [TBT] +Home.ProcOptions.NewProfile=New profile name: [TBT] +Home.ProcOptions.ButtonStarExecTooltip=Save or cancel profile edition before continue. [TBT] +Home.ProcOptions.CreateNewProfile=Create new profile [TBT] +Home.ProcOptions.AddScriptTask=Add script task [TBT] +Home.ProcOptions.StartProcessing=Start processing [TBT] +Home.ProcOptions.Table.Options=Options [TBT] +Home.ProcOptions.ScriptAlreadyExists=Script destination folder already has a file with this name. Please change the name of the source script first. [TBT] +Home.ProcessManager.StartingProcess=Hang on, we are starting your processing.. [TBT] +Home.ProcessManager.ProcessFailed=IPED execution failed.. [TBT] +Home.ProcessManager.ProcessRunning=IPED is processing.. [TBT] +Home.ProcessManager.ProcessFinished=Process finished successfully!! [TBT] +Home.ProcessManager.BackToCaseInfo=Back to case info [TBT] +Home.ProcessManager.ShowTerminalLog=View Processing Log [TBT] +Home.ProcessManager.OpenCase=Open case [TBT] +Home.ProcessManager.OpenCaseMsg=Wait... [TBT] +Home.ProcessManager.TerminalLog=Terminal log [TBT] +Home.ProcessManager.ExitApplication=Exit application [TBT] +Home.OpenCase.OpenCase=Open Case(s) [TBT] +Home.OpenCase.AddCaseToList=Add a case to the list [TBT] +Home.OpenCase.RemoveCaseFromList=Remove the case from list [TBT] +Home.OpenCase.SelectCaseFolder=Select case folder [TBT] +Home.OpenCase.OpenAllCasesInTheList=Open all cases in the list [TBT] +Home.OpenCase.EmptyCaseMessage=You need add at least one case to list [TBT] +Home.OpenCase.EmptyCaseMessageTitle=Empty case list [TBT] +Home.OpenCase.CaseLocation=Case location [TBT] +Home.OpenCase.CaseTableHeader=CASE LIST [TBT] +Home.IPEDMimeSeachList.showTikaMimeTypes=Show Tika mime types [TBT] +Home.configurables.AdvancedPanelLabel=Advanced [TBT] +Home.configurables.BasicPanelLabel=Basic configuration [TBT] +Home.configurables.BasicCarverPanelLabel=Carvers list [TBT] +Home.configurables.BasicParsersPanelLabel=Parsers list [TBT] +ScriptEditPanel.File=File:[TBT] +ScriptEditPanel.SelectTemplateLabel=Select Template:[TBT] +ScriptEditPanel.StartEditing=Start editing[TBT] +ScriptEditPanel.Preview=Preview[TBT] +ScriptEditPanel.ImportScript.tooltip=Load script from file[TBT] +ScriptEditPanel.ImportScript=Import script[TBT] +iped.app.home.configurables.ParsersConfigurablePanel.EmptyNameError=Parser name field empty. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.EmptyCommandError=Command field empty. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.EmptyMimeTypeError=Mime-types field empty. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.InvalidMimeTypeError=Invalid mimetype [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.UnregisteredMimeTypeError="Mime type specified is not registered [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.EmptyCharsetError=Charset field empty. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.InvalidFirstLinesToSkipError=Invalid value informed as number of first lines to skip. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.InvalidCharsetError=Invalid charset. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.EditVetoError=Edition of external parser in course. [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.CreateExternalParser=Create external parser [TBT] +iped.app.home.configurables.ParsersConfigurablePanel.NewExternalParserPanel=New external Parser [TBT] +ScriptEditPanel.scriptScopeWarn=The script file is saved in shared script folder, affecting all profile configurations. Do you want to continue editing? [TBT] +ReportDialog.InvestigatedNames=Investigated Name [TBT] +ReportDialog.organizationName=Organization Name [TBT] +ReportDialog.contact=Contact [TBT] +ReportDialog.caseNotes=Case notes [TBT] +Home.OpenCase.InavlidCasePath=Invalid Case Path[TBT] +Home.OpenCase.NoSearchApp=IPED-SearchApp not found [TBT] +Home.OpenCase.CaseNotFinished=The case process is not finished [TBT] +Home.OpenCase.CaseV3NotSupported=Cases from version 3 are not supported[TBT] +Home.NewCase.OpenCaseFileDialogTitle=Overwrite information? [TBT] +Home.NewCase.OpenCaseFileDialogMessage=Do you want to overwrite existing information with information from the file? [TBT] +Home.ProcessManager.ExistentCaseAlertMessage=A case already exists in the directory in the case destination folder. What do you wanna do? [TBT] +Home.ProcessManager.ExistentCaseAlertTitle=Existing case [TBT] +Home.Evidences.SkippedFoldersOnRecursiveEvidenceFind=Some folders were inaccessible and skipped when searching for evidences [TBT] +Home.Evidences.SkippedFoldersOnRecursiveEvidenceFindAlertTitle=Skipped Folders [TBT] +Home.Configurable.Enable=Enable [TBT] +Home.Configurable.Disable=Disable [TBT] \ No newline at end of file diff --git a/iped-app/resources/localization/iped-desktop-messages_pt_BR.properties b/iped-app/resources/localization/iped-desktop-messages_pt_BR.properties index 6de2ea764f..0fdd5356a1 100644 --- a/iped-app/resources/localization/iped-desktop-messages_pt_BR.properties +++ b/iped-app/resources/localization/iped-desktop-messages_pt_BR.properties @@ -29,7 +29,8 @@ AppLazyInitializer.errorTitle=Erro na inicialização AppListener.NoHits=0 Ocorrências AppListener.UncheckAll=Deseja realmente desmarcar todos os itens? AppListener.UncheckAll.Title=Confirmar -AppMain.NoCasesFile=Arquivo de casos inexistente: +AppMain.error.Title=Erro na inicialização +AppMain.NoCasesFile=Arquivo de casos inexistente: AppMain.warn.Title=Alerta na inicialização BookmarksController.HistoryDelimiter=-----------------------Histórico----------------------- BookmarksController.LoadError=Erro ao carregar marcadores\! @@ -77,7 +78,65 @@ BookmarksManager.UpdateTooltip=Atualizar comentários BookmarksManager.AlreadyExists=Nome de marcador já existente! BookmarksTreeModel.NoBookmarks=[Sem Marcadores] BookmarksTreeModel.RootName=Marcadores +Case.New=Novo +Case.NewCase=Novo Caso +Case.Open=Abrir +Case.OpenCase=Abrir Caso +Case.Options=Opções +Case.ProcessingOptions=Opções de Processamento +Case.CaseName=Nome +Case.CaseOutput=Diretório de Saída +Case.CaseChoose=Escolher... +Case.NonEmptyDirectoryAlert=O diretório {0} não está vazio. Será criado o diretório {1}. Deseja continuar? +Case.DatasourceType=Tipo de Entrada +Case.DatasourceInput=Arquivo de Entrada +Case.AddDatasource=Adicionar Fonte de Dados +Case.DataSourceName=Nome da Fonte de Dados +Case.DataSourceType=Tipo +Case.PersonId=CPF +Case.BusinessId=CNPJ +Case.PersonIdMask=###.###.###-## +Case.BusinessIdMask=##.###.###/####-## +Case.RemoveDatasource=Remover Fonte de Dados +Case.AddInput=Adicionar Entrada +Case.RemoveFile=Remover +Case.CaseSaveError=Ocorreu um erro ao salvar o caso: {0} +Case.CaseLoadError=Ocorreu um erro ao carregar o caso: {0} +Case.CaseFile=Arquivos de Caso do Iped +Case.SaveCase=Salvar +Case.Cancel=Cancelar +Case.enableLedDie=Habilitar LED DIE +Case.exportFileProps=Exportar Propriedades dos Arquivos +Case.enableLanguageDetect=Habilitar Detecção de Língua +Case.enableRegexSearch=Habilitar Busca de Expressões Regulares +Case.enableNamedEntityRecogniton=Enable Entity Recognition +Case.enableGraphGeneration=Habilitar Análise de Vínculos +Case.indexUnknownFiles=Indexar Arquivos Desconhecidos +Case.addUnallocated=Processar Espaço Não Alocado +Case.enableOCR=Habilitar OCR +Case.enableLedDieHelp=Habilita detecção de nudez. Para cada imagem cria os atributos "nudityScore" (ou "scoreNudez") (1 a 1000) e "nudityClass" (ou "classeNudez") (1 a 5) para ordenação e/ou filtro. +Case.exportFilePropsHelp=Exporta as propriedades de todos os arquivos para o arquivo "Lista de Arquivos.csv" +Case.enableLanguageDetectHelp=Habilita detecção de mais de 70 idiomas nos documentos. +Case.enableRegexSearchHelp=Vasculha o texto extraído dos itens por expressões como cpf, cnpj, emails, urls, cartões, valores, etc. +Case.enableNamedEntityRecognitonHelp=Função EXPERIMENTAL de reconhecimento de entidades mencionadas: nomes de pessoas, organizações e lugares. É necessário configuração adicional para habilitar. +Case.enableGraphGenerationHelp=Função EXPERIMENTAL para geração de mapa de vínculos. Depende da busca de expressões regulares. +Case.indexUnknownFilesHelp=Indexa arquivos sem decodificador específico, como binários, desconhecidos, pagefile, não alocado, etc. +Case.addUnallocatedHelp=Adiciona e processa áreas não alocadas de imagens via sleuthkit. +Case.enableOCRHelp=Habilita o OCR em imagens e PDFs digitalizados. Pode aumentar consideravelmente o tempo de processamento. +Case.Yes=Sim +Case.No=Não +Case.ProcessCase=Processar +Case.OptionsSaved=Opções salvas no arquivo {0}. +Case.OptionsSaveError==Ocorreu um erro ao salvar: {0} +Case.PERSON=Pessoa Física +Case.BUSINESS=Pessoa Jurídica +Case.GENERIC=Genérico +Case.PersonIdProperty=cpf +Case.BusinessIdProperty=cnpj +Case.Profile=Perfil +Case.ProfileHelp=Seleção de perfil de processamento. CategoryTreeModel.RootName=Categorias +CategoryTreeModel.Uncategorizables=Não Categorizado ColumnsManager.Advanced=Avançadas ColumnsManager.All=Todas ColumnsManager.Audio=Áudio @@ -102,19 +161,19 @@ ColumnsManager.AutoManageCols=Gerenciar colunas automaticamente (mais lento) ColumnsManager.LoadingCols=Carregando Colunas Populadas... ColumnsManager.Filter=[Digite para filtrar] ColumnsManager.WindowsEvt=Eventos do Windows -CopyProperties.Copying=Copiando +CopyProperties.Copying=Copiando CopyProperties.CSVDateFormat=dd/MM/yyyy HH:mm:ss z CopyProperties.CSVDelimiter=; -CopyProperties.from=\ de +CopyProperties.from=\ de DuplicatesTableModel.Duplicates=\ Duplicatas -ExportFiles.Copying=Copiando -ExportFiles.of=\ de -ExportFilesToZip.Copying=Copiando -ExportFilesToZip.from=\ de -ExportFileTree.Copied=Copiados -ExportFileTree.ExportError=Erro ao exportar arquivos. Verifique as permissões e o espaço disponível.\n -ExportFileTree.from=\ de -ExportIndexedTerms.Exported=Exportados +ExportFiles.Copying=Copiando +ExportFiles.of=\ de +ExportFilesToZip.Copying=Copiando +ExportFilesToZip.from=\ de +ExportFileTree.Copied=Copiados +ExportFileTree.ExportError=Erro ao exportar arquivos. Verifique as permissões e o espaço disponível.\n +ExportFileTree.from=\ de +ExportIndexedTerms.Exported=Exportados ExportIndexedTerms.ofWords=\ de termos. ExportToZIP.DefaultName=ArquivosExportados.zip ExportToZIP.DefaultPath=/home/caine/DADOS_EXPORTADOS @@ -137,7 +196,7 @@ Gallery.IncreaseThumbsSize=Aumentar tamanho das miniaturas Gallery.GalleryBlurFilter=Alternar filtro desfocado na galeria (use Ctrl+Q para aplicar globalmente) Gallery.GalleryGrayFilter=Alternar filtro de cinza na galeria (use Ctrl+W para aplicar globalmente) Gallery.ToggleVideoFrames=Alternar configuração de cenas para miniaturas de vídeos (Completa / Reduzida) -GraphAnalysis.GraphvizError=Erro ao testar ferramenta graphviz {0}. Ela está instalada? +GraphAnalysis.GraphvizError=Erro ao testar ferramenta graphviz {0}. Ela está instalada? GraphAnalysis.Expand=Expandir GraphAnalysis.ExpandConfiguration=Expandir (Filtro) GraphAnalysis.Expand.Links=Vínculos @@ -162,7 +221,7 @@ GraphAnalysis.Search=Buscar GraphAnalysis.Add=Adicionar GraphAnalysis.Cancel=Cancelar GraphAnalysis.Export=Exportar -GraphAnalysis.Id=Id. +GraphAnalysis.Id=Id GraphAnalysis.Type=Tipo GraphAnalysis.Quantity=Qtde GraphAnalysis.Property=Propriedade @@ -187,9 +246,9 @@ GraphAnalysis.MultiGraphError=Erro ao gerar os vínculos, verifique o log. GraphAnalysis.MultiGraphOk=Vínculos gerados com sucesso. GraphAnalysis.InitialGraphMsg=Grafo inicial pronto. Ele inclui apenas as entidades mais conectadas. KeywordListImporter.BookmarkPrefix=Resultados de pesquisa por: -KeywordListImporter.Msg.1=Importada(s) -KeywordListImporter.Msg.2=\ expressão(ões) com ocorrência(s) do total de -KeywordListImporter.SyntaxError=Erro de sintaxe nas seguintes expressões: +KeywordListImporter.Msg.1=Importada(s) +KeywordListImporter.Msg.2=\ expressão(ões) com ocorrência(s) do total de +KeywordListImporter.SyntaxError=Erro de sintaxe nas seguintes expressões: HashDialog.MD5Title=Hash MD5 do ZIP exportado ImageSimilarity.ExternalError=Não foi possível abrir a imagem selecionada. ImageSimilarity.ExternalTitle=Imagem Similar Externa @@ -329,11 +388,11 @@ ResultTableRowSorter.Sorting=Ordenando... RowComparator.SortCanceled=Ordenação cancelada. SearchStateFilter.BookmarksFile=Arquivo de Marcadores SubitemTableModel.Subitens=\ Anexos/Subitens -TextParserListener.Found=Encontradas +TextParserListener.Found=Encontradas TextParserListener.hits=\ ocorrências TreeViewModel.RootName=Evidências UISearcher.Canceled=Pesquisa cancelada\! -UISearcher.Error.Msg=Erro de sintaxe de pesquisa: +UISearcher.Error.Msg=Erro de sintaxe de pesquisa: UISearcher.Error.Title=Error UnsupportedIcon.Unavailable=Miniatura não suportada ViewerController.OfficeViewerUnSupported=Visualizador Office não mais suportado no java 32bits! Instale um java 64bits. @@ -352,10 +411,10 @@ TimeLineGraph.highlightEventItensOnPeriod=Destacar itens do evento no periodo TimeLineGraph.highlightItensOnPeriod=Destacar itens do periodo TimeLineGraph.checkEventItensOnPeriod=Marcar itens do evento no periodo TimeLineGraph.checkItensOnPeriod=Marcar itens do periodo -TimeLineGraph.filterBefore=Filtrar anteriores a -TimeLineGraph.filterAfter=Filtrar posteriores a -TimeLineGraph.selectBefore=Destacar anteriores a -TimeLineGraph.selectAfter=Destacar posteriores a +TimeLineGraph.filterBefore=Filtrar anteriores a +TimeLineGraph.filterAfter=Filtrar posteriores a +TimeLineGraph.selectBefore=Destacar anteriores a +TimeLineGraph.selectAfter=Destacar posteriores a TimeLineGraph.filterAllDefinedIntervals=Filtrar os intervalos definidos TimeLineGraph.selectItensOnThisInterval=Destacar itens neste intervalo TimeLineGraph.deleteInterval=Excluir intervalo @@ -441,4 +500,159 @@ FieldValuePopupMenu.LessThan=Menores que.. FieldValuePopupMenu.Equals=Igual a... FieldValuePopupMenu.StartsWith=Iniciam com... FieldValuePopupMenu.Clear=Limpar -FieldValuePopupMenu.Filter=Filtrar \ No newline at end of file +FieldValuePopupMenu.Filter=Filtrar +Home.StartNewCase=INICIAR NOVO CASO +Home.OpenCase=ABRIR CASO +Home.Config=CONFIGURAÇÕES +Home.LocalEnviromentConfiguration=Configurações de ambiente local +Home.DefaultThreadValue=Aplica o valor padrão de Thread +Home.ChooseDefaultIndexTempFolder=Selecione a pasta para temporário +Home.DefaultIndexTempToolTip=Seleciona o valor "Default" (Default é o diretório temporário do seu sistema operacional) +Home.Language=Idioma +Home.NumberOfThreads=N de Threads +Home.TempFolder=Diretório para temporários +Home.HashDatabase=Diretório do HashDB +Home.TSKJar=Diretório do Jar do TSk +Home.TSKJarDialogTtitle=Informe o JAR do Sleuthkit +Home.OptionalPluginsPath=Diretório dos plugins opcionais +Home.OptPluginDialogTtitle=Selecione a pasta dos plugins +Home.IndexTempOnSSDLabel=Marque esta opção se o "Diretório para temporários" estiver em um dispositivo SSD +Home.InformHashDBFile=Informe o arquivo do Banco de dados de Hash +Home.Save=Salvar +Home.Cancel=Cancelar +Home.Next=Próximo +Home.Back=Voltar +Home.Select=Selecionar +Home.Active=Ativo +Home.Inactive=Inativo +Home.LanguagePtBR=Português Brasileiro +Home.LanguageEN=Inglês +Home.LanguageIT=Italiano +Home.LanguageDE=Alemão +Home.LanguageEsAr=Espanhol Argentino +Home.LanguageChangeMessage=Você selecionou um idioma diferente. Reinicie o IPED para que o novo idioma seja aplicado. +Home.LanguageChangeTitle=Modificação de idioma +Home.CaseInformation=Informações do caso +Home.CaseInformationTollTip=Detalhes do caso +Home.Evidences=Evidências +Home.EvidencesToolTip=Lista de evidências a serem processadas +Home.ProcessOptions=Opções de processamento +Home.ProcessOptionsToolTip=Página de seleção de Tasks para o processamento +Home.ProcessingTab=Processamento +Home.ProcessingTabTooltip=Acompanhamento da evolução do processamento +Home.NewCase.CaseOutput=*Pasta do caso +Home.NewCase.ChooseCaseOutput=Selecione a pasta do caso +Home.NewCase.IsCaseOutputOnSSD=A pasta do caso esta em um SSD? +Home.NewCase.IsCaseOutputOnSSDToolTip=Ative se a pasta de saída do caso estiver em um SSD. Se ativado, o índice é criado diretamente na pasta do caso, não em indexTemp, portanto, você precisará de menos espaço livre na pasta temp. +Home.NewCase.CaseOutputRequired=A pasta de destino do caso é obrigatória +Home.NewCase.CaseOutputRequiredTitle=Pasta de destino do caso +Home.NewCase.CaseOutputPermission=É necessário permissão de leitura e escrita na pasta de destino do caso. +Home.NewCase.CaseOutputPermissionTitle=Pasta de destino do caso +Home.NewCase.CaseOutPutOptionsRequired=Você precisa selecionar uma opção para a pasta de saida do caso. +Home.NewCase.SaveCaseData=Salvar dados do caso +Home.NewCase.LoadCaseData=Carregar dados do caso +Home.NewCase.ChooseCaseInfoFileOutput=Selecione o pasta de destino do arquivo do caso +Home.NewCase.ChooseCaseInfoFile=Informe o arquivo dos dados do caso +Home.ExistentCaseAlert=Ja existe um caso na pasta de destino informada. Escolha uma opção abaixo ou selecione uma nova pasta: +Home.AppendExistentCase=Adicionar - Adiciona este caso ao caso existente +Home.ContinueExistentCase=Continuar - Continua o processamento do caso existente +Home.RestartExistentCase=Reiniciar - Reinicia o processamento do caso existente +Home.Evidences.AddFolder=Adicionar Pasta +Home.Evidences.AddFile=Adicionar arquivo +Home.Evidences.AddImagesRecursively=Adicionar imagens recursivamente +Home.Evidences.AddDisk=Adicionar disco +Home.Evidences.SelectFolder=Selecione a pasta +Home.Evidences.SelectFile=Selecione o arquivo +Home.Evidences.AddFileTitle=Adicionar arquivo +Home.Evidences.ChooseSourceFolder=Selecione a pasta de origem da pesquisa +Home.Evidences.ImageSearchError=Erro na pesquisa de imagens +Home.Evidences.PathMustBeDirectory=O Path deveria ser um diretório +Home.Evidences.Title=Evidências +Home.Evidences.Table.FileName=Nome do arquivo +Home.Evidences.Table.Alias=Pseudônimo +Home.Evidences.Table.Path=Caminho +Home.Evidences.Table.Options=Opções +Home.Evidences.DialogTitle=Detalhes da evidência +Home.Evidences.Dialog.FileName=Nome do arquivo: +Home.Evidences.Dialog.Path=Localização (Path): +Home.Evidences.Dialog.Alias=Pseudônimo: +Home.Evidences.Dialog.EvidenceDesc=Descrição da evidencia: +Home.Evidences.Dialog.Password=Senha (Imagem APFS): +Home.Evidences.Dialog.TimeZone=TimeZone (FAT FS): +Home.Evidences.Dialog.BlockSize=Block size (0 = padrão): +Home.Evidences.DisksDialog.Title=Selecione o disco a ser processado +Home.Evidences.DisksDialog.Name=Nome +Home.Evidences.DisksDialog.Model=Modelo +Home.Evidences.DisksDialog.Size=Tamanho +Home.Evidences.DisksDialog.Serial=Serial +Home.Evidences.DisksDialog.Select=Selecionar +Home.Evidences.DisksDialog.NotAdmin=Você precisa ser administrador para processar discos físicos +Home.Evidences.NoEvidencesAlert=Você precisa seleciona pelo menos uma evidência para continuar +Home.Evidences.NoEvidencesAlertTitle=Nenhuma evidência selecionada +Home.ProcOptions.Title=Opções de processamento +Home.ProcOptions.ExecProfile=Perfil de execução: +Home.ProcOptions.NewProfile=Nome do novo perfil: +Home.ProcOptions.ButtonStarExecTooltip=Salve ou cancele a edição do perfil para continuar. +Home.ProcOptions.CreateNewProfile=Criar novo perfil +Home.ProcOptions.AddScriptTask=Adicionar novo script +Home.ProcOptions.StartProcessing=Iniciar processamento +Home.ProcOptions.Table.Options=Opções +Home.ProcOptions.ScriptAlreadyExists=Pasta de destino já contém um arquivo com este nome. Por favor, modifique o nome do arquivo. +Home.ProcessManager.StartingProcess=Aguarde estamos iniciando o seu processamento +Home.ProcessManager.ProcessFailed=A execução do IPED falhou.. +Home.ProcessManager.ProcessRunning=O IPED esta processando.. +Home.ProcessManager.ProcessFinished=Processamento concluído com sucesso!! +Home.ProcessManager.BackToCaseInfo=Voltar para as informações do caso +Home.ProcessManager.ShowTerminalLog=Exibir log do processamento +Home.ProcessManager.OpenCase=Abrir o caso +Home.ProcessManager.OpenCaseMsg=Aguarde... +Home.ProcessManager.TerminalLog=Log do terminal +Home.ProcessManager.ExitApplication=Sair da aplicação +Home.OpenCase.OpenCase=Abrir Caso(s) +Home.OpenCase.AddCaseToList=Adicionar um caso a lista +Home.OpenCase.RemoveCaseFromList=Remover caso da lista +Home.OpenCase.SelectCaseFolder=Selecione a pasta do caso +Home.OpenCase.OpenAllCasesInTheList=Abrir os casos da lista +Home.OpenCase.EmptyCaseMessage=Você precisa adicionar pelo menos um caso na lista +Home.OpenCase.EmptyCaseMessageTitle=Lista de casos vazia +Home.OpenCase.CaseLocation=Localização do caso +Home.OpenCase.CaseTableHeader=LISTA DE CASOS +Home.IPEDMimeSeachList.showTikaMimeTypes=Mostrar tipos MIME do Tika +Home.configurables.AdvancedPanelLabel=Avançado +Home.configurables.BasicPanelLabel=Configuração básica +Home.configurables.BasicCarverPanelLabel=Lista de carvers +Home.configurables.BasicParsersPanelLabel=Lista de parsers +ScriptEditPanel.File=Arquivo: +ScriptEditPanel.SelectTemplateLabel=Selecione um modelo: +ScriptEditPanel.StartEditing=Editar +ScriptEditPanel.Preview=Visualizar +ScriptEditPanel.ImportScript.tooltip=Importa o script de um arquivo +ScriptEditPanel.ImportScript=Importar +iped.app.home.configurables.ParsersConfigurablePanel.EmptyNameError=Campo nome do parser vazio. +iped.app.home.configurables.ParsersConfigurablePanel.EmptyCommandError=Campo comando vazio. +iped.app.home.configurables.ParsersConfigurablePanel.EmptyMimeTypeError=Campo tipo MIME vazio. +iped.app.home.configurables.ParsersConfigurablePanel.InvalidMimeTypeError=Tipo MIME inválido. +iped.app.home.configurables.ParsersConfigurablePanel.UnregisteredMimeTypeError=Tipo MIME não registrado +iped.app.home.configurables.ParsersConfigurablePanel.EmptyCharsetError=Campo conjunto de caracteres vazio. +iped.app.home.configurables.ParsersConfigurablePanel.InvalidFirstLinesToSkipError=Valor inválido para o campo ignorar primeiras linhas. +iped.app.home.configurables.ParsersConfigurablePanel.InvalidCharsetError=Conjunto de caracteres inválido. +iped.app.home.configurables.ParsersConfigurablePanel.EditVetoError=Edição de parser externo em andamento. +iped.app.home.configurables.ParsersConfigurablePanel.CreateExternalParser=Criar parser externo +iped.app.home.configurables.ParsersConfigurablePanel.NewExternalParserPanel=Novo parser externo +ScriptEditPanel.scriptScopeWarn=O arquivo do script é salvo em uma pasta comum a todos os perfis afetando todos eles. Você deseja continuar a edição? +ReportDialog.InvestigatedNames=Nome dos investigados +ReportDialog.organizationName=Nome da organização +ReportDialog.contact=Contato +ReportDialog.caseNotes=Notas do caso +Home.OpenCase.InavlidCasePath=O diretório do caso é invalido +Home.OpenCase.NoSearchApp=Não foi encontrado o IPED-SearchApp +Home.OpenCase.CaseNotFinished=O processamento do caso selecionado não foi concluído +Home.OpenCase.CaseV3NotSupported=Casos da versão 3 não são suportados +Home.NewCase.OpenCaseFileDialogTitle=Sobrescrever as informações? +Home.NewCase.OpenCaseFileDialogMessage=Deseja sobrescrever as informação existentes com as informações do arquivo? +Home.ProcessManager.ExistentCaseAlertMessage=Já existe um caso no diretório na pasta de destino do caso. O que deseja fazer? +Home.ProcessManager.ExistentCaseAlertTitle=Caso existente +Home.Evidences.SkippedFoldersOnRecursiveEvidenceFind=Algumas pastas estavam inacessíveis e foram ignoradas durante a busca +Home.Evidences.SkippedFoldersOnRecursiveEvidenceFindAlertTitle=Pastas ignoradas +Home.Configurable.Enable=Habilitar +Home.Configurable.Disable=Desabilitar \ No newline at end of file diff --git a/iped-app/resources/localization/iped-engine-messages.properties b/iped-app/resources/localization/iped-engine-messages.properties index 2a9e8db475..3a5507a72c 100644 --- a/iped-app/resources/localization/iped-engine-messages.properties +++ b/iped-app/resources/localization/iped-engine-messages.properties @@ -122,4 +122,246 @@ GraphAnalysis.LinksContacts=Contacts GraphAnalysis.LinksEmails=E-mails GraphAnalysis.LinksInstantMessages=Instant Messages GraphAnalysis.LinksWireless=Wireless Networks -GraphAnalysis.LinksDocuments=Documents \ No newline at end of file +GraphAnalysis.LinksDocuments=Documents +iped.engine.task.ImageThumbTask=Image thumbs creation +iped.engine.config.ImageThumbTaskConfig=Thumbs parameters +iped.engine.config.ImageThumbTaskConfig.imgConvTimeoutPerMB=Timeout per MB +iped.engine.config.ImageThumbTaskConfig.imgConvTimeout=Total timeout +iped.engine.config.ImageThumbTaskConfig.lowResDensity=Low resolution density +iped.engine.config.ImageThumbTaskConfig.highResDensity=High resolution density +iped.engine.config.ImageThumbTaskConfig.maxMPixelsInMemory=Max memory used (MB) +iped.engine.config.ImageThumbTaskConfig.logGalleryRendering=Log gallery rendering +iped.engine.config.ImageThumbTaskConfig.imgThumbSize=Image thumb size +iped.engine.config.ImageThumbTaskConfig.externalConversionTool=External conversion tool +iped.engine.config.ImageThumbTaskConfig.enableExternalConv=Enable external conversion +iped.engine.config.ImageThumbTaskConfig.extractThumb=Extract thumb +iped.engine.config.ImageThumbTaskConfig.galleryThreads=Number of gallery threads +iped.engine.graph.GraphTaskConfig=Graph creation +iped.engine.graph.GraphTaskConfig.comment=Comments +iped.engine.graph.GraphTaskConfig.defaultBusinessEntity=Default Business Entity +iped.engine.graph.GraphTaskConfig.defaultEntity=Default Entity +iped.engine.graph.GraphTaskConfig.defaultPersonEntity=Default Person Entity +iped.engine.graph.GraphTaskConfig.defaultRelationship=Default relationship +iped.engine.graph.GraphTaskConfig.detectPhonesOnOtherMimes=Detect phone number on other mimetype files +iped.engine.graph.GraphTaskConfig.entities=Entities +iped.engine.task.HTMLReportTask=HTML Report Generation +iped.engine.config.HtmlReportTaskConfig=HTML generation parameters +iped.engine.config.HtmlReportTaskConfig.EnableThumbsGallery=Enable thumbs gallery +iped.engine.config.HtmlReportTaskConfig.ThumbSize=Thumb size +iped.engine.config.HtmlReportTaskConfig.Examiner=Examiner name +iped.engine.config.HtmlReportTaskConfig.Report=Exame ID +iped.engine.config.HtmlReportTaskConfig.RecordDate=Record date +iped.engine.config.HtmlReportTaskConfig.EnableImageThumbs=Enable image thumbs +iped.engine.config.HtmlReportTaskConfig.ThumbsPerPage=Thumbs per page +iped.engine.config.HtmlReportTaskConfig.ItemsPerPage=Items per page +iped.engine.config.HtmlReportTaskConfig.Title=Report Title +iped.engine.config.HtmlReportTaskConfig.ReportDate=Report date +iped.engine.config.HtmlReportTaskConfig.Material=Material ID +iped.engine.config.HtmlReportTaskConfig.EnableVideoThumbs=Enable video thumbs +iped.engine.config.HtmlReportTaskConfig.RequestDoc=Request document ID +iped.engine.config.HtmlReportTaskConfig.ExaminerID=Examiner ID +iped.engine.config.HtmlReportTaskConfig.Requester=Requester Name +iped.engine.config.HtmlReportTaskConfig.RequestDate=Request Date +iped.engine.config.HtmlReportTaskConfig.VideoStripeWidth=Video stripe width +iped.engine.config.HtmlReportTaskConfig.Header=Report header +iped.engine.config.HtmlReportTaskConfig.Investigation=Investigation name +iped.engine.config.HtmlReportTaskConfig.FramesPerStripe=Video frames per stripe +iped.engine.config.HtmlReportTaskConfig.Record=Request document ID +iped.engine.config.HtmlReportTaskConfig.EnableCategoriesList=Enable categories list +iped.engine.task.ParsingTask=Content parsing +iped.engine.task.HashTask=Hash Calculation Task +iped.engine.task.HashTask.tooltip=Hash Calculation Task +iped.engine.config.HashTaskConfig=Hash configurations +iped.engine.config.HashTaskConfig.tooltip=Configure algorithms used to calculate item hashes +iped.engine.config.HashTaskConfig.hashes=Algorithms +iped.engine.config.HashTaskConfig.hashes.tooltip=Algorithms used to calculate item hashes +iped.engine.task.SignatureTask=Mime-type identification +iped.engine.task.SignatureTask.tooltip=Mime-type identification based on FreeDesktop specification.
(https://specifications.freedesktop.org/shared-mime-info-spec/latest/ar01s02.html). +iped.engine.config.SignatureConfig=Mime-type identification rules +iped.engine.config.SignatureConfig.tooltip=Mime-type identification rules based on FreeDesktop specification.
(https://specifications.freedesktop.org/shared-mime-info-spec/latest/ar01s02.html). +iped.engine.config.CategoryConfig=Categorization configuration based on mime-types +iped.engine.config.CategoryConfig.tooltip=Specify which items are to be classified in each category based on their mime-types. Use drag and drop operations. +iped.engine.task.SetCategoryTask=Item categorization +iped.engine.task.HashDBLookupTask=Known hash database matching +iped.engine.task.HashDBLookupTask.tooltip=Populates item with properties from known hashes database. +iped.engine.task.DuplicateTask=Duplicate finding +iped.engine.task.DuplicateTask.tooltip=Correlates duplicate items in the case based on their hash +iped.engine.task.transcript.AudioTranscriptTask=Audio Transcription +iped.engine.config.AudioTranscriptConfig=Audio Transcription Parameters +iped.engine.config.AudioTranscriptConfig.implementationClass=Implementation class +iped.engine.config.AudioTranscriptConfig.implementationClass.tooltip=Full name of java class that will execute the audio transcription algorithm. +iped.engine.config.AudioTranscriptConfig.language=Language +iped.engine.config.AudioTranscriptConfig.convertCommand=Conversion to WAV command +iped.engine.config.AudioTranscriptConfig.mimesToProcess=Mime-types to process +iped.engine.config.AudioTranscriptConfig.timeout=Transcription timeout +iped.engine.config.AudioTranscriptConfig.minWordScore=Minimum word score +iped.engine.config.AudioTranscriptConfig.serviceRegion=Service Region +iped.engine.config.AudioTranscriptConfig.maxConcurrentRequests=Maximum concurrent requests +iped.engine.config.AudioTranscriptConfig.requestIntervalMillis=Request interval (ms) +iped.engine.config.AudioTranscriptConfig.googleModel=Google model +iped.engine.task.video.VideoThumbTask=Video thumb creation +iped.engine.task.video.VideoThumbTask.tooltip=Video thumb creation +iped.engine.config.VideoThumbsConfig=Video Thumb parameters +iped.engine.config.VideoThumbsConfig.tooltip=Thumb parameters +iped.engine.config.VideoThumbsConfig.Layout=Layout +iped.engine.config.VideoThumbsConfig.Timeouts=Timeouts +iped.engine.config.VideoThumbsConfig.Verbose=Verbose +iped.engine.config.VideoThumbsConfig.GalleryThumbs=Gallery thumbs +iped.engine.config.VideoThumbsConfig.enableVideoThumbsSubitems=Enable subitems +iped.engine.config.VideoThumbsConfig.enableVideoThumbsOriginalDimension=Enable original dimension +iped.engine.config.VideoThumbsConfig.maxDimensionSize=Max dimension size +iped.engine.task.QRCodeTask=QRCode extraction +iped.engine.task.regex.RegexTask=Regular Expression matches extraction +iped.engine.config.RegexTaskConfig=Regular expressions +iped.engine.config.RegexTaskConfig.tooltip=Regular expressions +iped.engine.config.RegexTaskConfig.formatMatches=Format matches +iped.engine.config.RegexTaskConfig.formatMatches.tooltip=Format matches +iped.engine.task.LanguageDetectTask=Language detection +iped.engine.task.LanguageDetectTask.tooltip=Detects items content language +iped.engine.task.NamedEntityTask=Named entity detection +iped.engine.task.NamedEntityTask.tooltip=Detects named entities in item content +iped.engine.config.NamedEntityTaskConfig=Named entity parameters +iped.engine.config.NamedEntityTaskConfig.NERImpl=Implementation class +iped.engine.config.NamedEntityTaskConfig.langModel_0=Language model +iped.engine.config.NamedEntityTaskConfig.minLangScore=Minimum language score +iped.engine.config.NamedEntityTaskConfig.mimeTypesToIgnore=Ignored mime-types +iped.engine.config.NamedEntityTaskConfig.categoriesToIgnore=Ignored categories +iped.engine.task.ExportFileTask=File export +iped.engine.config.ExportByCategoriesConfig=Categories to export +iped.engine.config.ExportByKeywordsConfig=Export based on keyword match +iped.engine.task.EmbeddedDiskProcessTask=Embedded disk extraction +iped.engine.task.MakePreviewTask=Preview creation task +iped.engine.config.MakePreviewConfig=Mime types selection +iped.engine.config.MakePreviewConfig.supportedMimeTypes=Supported mime types +iped.engine.config.MakePreviewConfig.supportedMimeTypesWithLinks=Supported mime types with links +iped.engine.task.DocThumbTask=Document thumbs creation +iped.engine.config.DocThumbTaskConfig=Thumbs config +iped.engine.config.DocThumbTaskConfig.pdfThumbs=PDF thumbs +iped.engine.config.DocThumbTaskConfig.libreOfficeThumbs=Libre Office Thumbs +iped.engine.config.DocThumbTaskConfig.pdfTimeout=PDF thumb creation timeout +iped.engine.config.DocThumbTaskConfig.libreOfficeTimeout=Libre Office thumb creation timeout +iped.engine.config.DocThumbTaskConfig.timeoutIncPerMB=Timeout increment per item size (MB) +iped.engine.config.DocThumbTaskConfig.thumbSize=Thumb size +iped.engine.config.DocThumbTaskConfig.maxPdfExternalMemory=Maximun PDF external memory +iped.engine.task.die.DIETask=Explicit image detection +iped.engine.task.die.DIETask.tooltip=Attributes nudity scores to images content +iped.engine.task.similarity.ImageSimilarityTask=Image characteristic vector extraction +iped.engine.task.similarity.ImageSimilarityTask.tooltip=Extracts characteristic vector from images to use in similar image searches +iped.engine.task.PhotoDNATask=Photo DNA calculation +iped.engine.config.PhotoDNAConfig=Photo DNA calculation parameters +iped.engine.config.PhotoDNAConfig.computeFromThumbnail=Compute from thumbnail +iped.engine.config.PhotoDNAConfig.minFileSize=Minimum file size +iped.engine.config.PhotoDNAConfig.skipHashDBFiles=Ignores files found in hash database +iped.engine.task.PhotoDNALookup=Photo DNA database match +iped.engine.task.PhotoDNALookup.tooltip=Extracts properties from database based on Photo DNA value +iped.engine.config.PhotoDNALookupConfig=Database lookup parameters +iped.engine.config.PhotoDNALookupConfig.statusHashDBFilter=Hash status filter +iped.engine.config.PhotoDNALookupConfig.maxSimilarityDistance=Maximum similarity distance +iped.engine.config.PhotoDNALookupConfig.searchRotatedAndFlipped=Search for rotated or flipped image +iped.engine.task.carver.LedCarveTask=Carve items based on LED database +iped.engine.task.carver.LedCarveTask.tooltip=Carve items based on first 64K bytes hash match information found in LED database +iped.engine.task.carver.CarverTask=Carve items +iped.engine.task.carver.CarverTask.tooltip=Carve items based on customized carvers +iped.engine.task.carver.KnownMetCarveTask=Carve Emule knownmet files +iped.engine.task.carver.KnownMetCarveTask.tooltip=Carve Emule knownmet files +iped.engine.task.FragmentLargeBinaryTask=Fragments large binary files +iped.engine.config.SplitLargeBinaryConfig=Fragmentation parameters +iped.engine.config.SplitLargeBinaryConfig.minItemSizeToFragment=Minimum size to fragment +iped.engine.config.SplitLargeBinaryConfig.itemFragmentSize=Fragment size +iped.engine.config.SplitLargeBinaryConfig.fragmentOverlapSize=Fragment overlap size +iped.engine.task.EntropyTask=Entropy calculation +iped.engine.task.EntropyTask.tooltip=Item entropy calculation +iped.engine.task.MinIOTask=MinIO +iped.engine.config.MinIOConfig=MinIO configuration +iped.engine.config.MinIOConfig.host=Host IP address +iped.engine.config.MinIOConfig.port=Host TCP port +iped.engine.config.MinIOConfig.zipFilesMaxSize=Maximum size of zip files +iped.engine.config.MinIOConfig.updateRefsToMinIO=Update references to MinIO +iped.engine.config.MinIOConfig.timeOut=Timeout +iped.engine.config.MinIOConfig.retries=Number of retries +iped.engine.task.index.ElasticSearchIndexTask=Elastic search integration +iped.engine.config.ElasticSearchTaskConfig=Elastic Seach parameters +iped.engine.config.ElasticSearchTaskConfig.host=Server Host IP Address +iped.engine.config.ElasticSearchTaskConfig.port=Server Host Port +iped.engine.config.ElasticSearchTaskConfig.protocol=Server Host Protocol +iped.engine.config.ElasticSearchTaskConfig.index.number_of_shards=Number of shards +iped.engine.config.ElasticSearchTaskConfig.index.number_of_replicas=Number of replicas +iped.engine.config.ElasticSearchTaskConfig.min_bulk_size=Minimum bulk size +iped.engine.config.ElasticSearchTaskConfig.min_bulk_items=Minimum bulk items +iped.engine.config.ElasticSearchTaskConfig.max_async_requests=Maximum asynchronous requests +iped.engine.config.ElasticSearchTaskConfig.timeout_millis=Timeout (ms) +iped.engine.config.ElasticSearchTaskConfig.connect_timeout_millis=Connection timeout +iped.engine.config.ElasticSearchTaskConfig.index.mapping.total_fields.limit=Maximum number of fields +iped.engine.config.ElasticSearchTaskConfig.useCustomAnalyser=Use custom analyser +iped.engine.config.ElasticSearchTaskConfig.validateSSL=Validate SSL connection +iped.engine.config.ElasticSearchTaskConfig.useTermVector=Use term vector +iped.engine.task.index.IndexTask=Indexing +iped.engine.task.index.IndexTask.tooltip=Lucene indexing of items content and metadata. +iped.engine.config.IndexTaskConfig=Indexing parameters +iped.engine.config.IndexTaskConfig.indexUnallocated=Index unallocated space +iped.engine.config.IndexTaskConfig.convertCharsToLowerCase=Convert characters to lower case +iped.engine.config.IndexTaskConfig.convertCharsToAscii=Convert characters to ASCII +iped.engine.config.IndexTaskConfig.extraCharsToIndex=Additional characters to index +iped.engine.config.IndexTaskConfig.filterNonLatinChars=Filter non latin characters +iped.engine.config.IndexTaskConfig.textSplitSize=Text split size +iped.engine.config.IndexTaskConfig.useNIOFSDirectory=Use NIO file system +iped.engine.config.IndexTaskConfig.forceMerge=Force merge +iped.engine.config.IndexTaskConfig.storeTermVectors=Store term vectors +iped.engine.config.IndexTaskConfig.maxTokenLength=Maximum token length +iped.engine.config.IndexTaskConfig.commitIntervalSeconds=Index commit interval +iped.engine.graph.GraphTask=Graph creation +iped.engine.task.ExportCSVTask=Export properties to CSV +iped.engine.task.ExportCSVTask.tooltip=Export properties to CSV file +iped.engine.config.CategoryToExpandConfig=Categories to expand +iped.engine.config.CategoryToExpandConfig.tooltip=Categories to expand subitems including them on the parsing queue. +iped.engine.config.ParsingTaskConfig=General parsing parameters +iped.engine.config.ParsingTaskConfig.enableExternalParsing=Enable external parsing +iped.engine.config.ParsingTaskConfig.numExternalParsers=Number of external parser processes +iped.engine.config.ParsingTaskConfig.externalParsingMaxMem=Maximum memory per external parser process +iped.engine.config.ParsingTaskConfig.parseUnknownFiles=Parse unknown files +iped.engine.config.ParsingTaskConfig.parseCorruptedFiles=Parse corrupted files +iped.engine.config.ParsingTaskConfig.timeOut=Item parsing timeout +iped.engine.config.ParsingTaskConfig.timeOutPerMB=Item parsing timeout increment per MB +iped.engine.config.ParsingTaskConfig.minRawStringSize=Minimum raw string size +iped.engine.config.ParsingTaskConfig.phoneParsersToUse=Phone parsers to use +iped.engine.config.ParsingTaskConfig.sortPDFChars=Sort PDF characters +iped.engine.config.ParsingTaskConfig.processImagesInPDFs=Process images in PDFs +iped.engine.config.ParsingTaskConfig.storeTextCacheOnDisk=Store text cache on disk +iped.engine.config.OCRConfig=OCR parsing +iped.engine.config.OCRConfig.enableOCR=Enable OCR +iped.engine.config.OCRConfig.OCRLanguage=OCR Language +iped.engine.config.OCRConfig.pageSegMode=Page segmentation mode +iped.engine.config.OCRConfig.minFileSize2OCR=Minimum image file size to process OCR +iped.engine.config.OCRConfig.pdfToImgResolution=PDF to Image resolution +iped.engine.config.OCRConfig.maxPDFTextSize2OCR=Maximum PDF text size to OCR +iped.engine.config.OCRConfig.pdfToImgLib=PDF to image library +iped.engine.config.OCRConfig.externalPdfToImgConv=External PDF to image conversion +iped.engine.config.OCRConfig.externalConvMaxMem=Maximum memory for external PDF conversion +iped.engine.config.OCRConfig.processNonStandard=Process non standard +iped.engine.config.OCRConfig.maxConvImageSize=Maximum conversion image size +iped.engine.config.ParsersConfig=Specific Parsers +iped.engine.config.ExternalParsersConfig=External parsers +iped.engine.config.FileSystemConfig=Evidence options +iped.engine.config.FileSystemConfig.robustImageReading=Robust image reading +iped.engine.config.FileSystemConfig.numImageReaders=Number of readers +iped.engine.config.FileSystemConfig.addUnallocated=Process unallocated space +iped.engine.config.FileSystemConfig.addFileSlacks=Process file slack space +iped.engine.config.FileSystemConfig.minOrphanSizeToIgnore=Minimun orphan files not to ignore +iped.engine.config.FileSystemConfig.unallocatedFragSize=Size of unallocated space fragments +iped.engine.config.FileSystemConfig.ignoreHardLinks=Ignore Hard Links +iped.engine.config.FileSystemConfig.skipFolderRegex=Skip folders that matches regex +iped.engine.task.SkipCommitedTask=Skip commited task +iped.engine.task.SkipCommitedTask.tooltip=Skip commited task +iped.engine.task.TempFileTask=Temporary file task +iped.engine.task.TempFileTask.tooltip=Creates local temporary file to avoid repetitive network, decompression and slow source commands. +iped.engine.task.SetTypeTask=Mimetype classification +iped.engine.task.SetTypeTask.tooltip=Item classification based on its mime-type. +iped.engine.task.IgnoreHardLinkTask=Ignore hard link references +iped.engine.task.IgnoreHardLinkTask.tooltip=Ignores content processing of hard link references. +iped.engine.task.RefineCategoryTask=Refine categories +iped.engine.task.RefineCategoryTask.tooltip=Refines the categorization of found items. +iped.engine.task.PythonTask.FaceRecognitionTask.py=Face recognition task +iped.engine.config.DefaultTaskPropertiesConfig=Face recognition +iped.engine.config.DefaultTaskPropertiesConfig.maxResolution=Max. resolution +iped.engine.config.DefaultTaskPropertiesConfig.faceDetectionModel=Face detection model +iped.engine.config.DefaultTaskPropertiesConfig.upSampling=Up Sampling \ No newline at end of file diff --git a/iped-app/resources/localization/iped-engine-messages_de_DE.properties b/iped-app/resources/localization/iped-engine-messages_de_DE.properties index 6d27eda5a3..6acdded66b 100644 --- a/iped-app/resources/localization/iped-engine-messages_de_DE.properties +++ b/iped-app/resources/localization/iped-engine-messages_de_DE.properties @@ -123,3 +123,245 @@ GraphAnalysis.LinksEmails=E-Mails GraphAnalysis.LinksInstantMessages=Sofort-Nachrichten GraphAnalysis.LinksWireless=kabellose Netzwerke GraphAnalysis.LinksDocuments=Dokumente +iped.engine.task.ImageThumbTask=Image thumbs creation [TBT] +iped.engine.config.ImageThumbTaskConfig=Thumbs parameters [TBT] +iped.engine.config.ImageThumbTaskConfig.imgConvTimeoutPerMB=Timeout per MB [TBT] +iped.engine.config.ImageThumbTaskConfig.imgConvTimeout=Total timeout [TBT] +iped.engine.config.ImageThumbTaskConfig.lowResDensity=Low resolution density [TBT] +iped.engine.config.ImageThumbTaskConfig.highResDensity=High resolution density [TBT] +iped.engine.config.ImageThumbTaskConfig.maxMPixelsInMemory=Max memory used (MB) [TBT] +iped.engine.config.ImageThumbTaskConfig.logGalleryRendering=Log gallery rendering [TBT] +iped.engine.config.ImageThumbTaskConfig.imgThumbSize=Image thumb size [TBT] +iped.engine.config.ImageThumbTaskConfig.externalConversionTool=External conversion tool [TBT] +iped.engine.config.ImageThumbTaskConfig.enableExternalConv=Enable external conversion [TBT] +iped.engine.config.ImageThumbTaskConfig.extractThumb=Extract thumb [TBT] +iped.engine.config.ImageThumbTaskConfig.galleryThreads=Number of gallery threads [TBT] +iped.engine.graph.GraphTaskConfig=Graph creation [TBT] +iped.engine.graph.GraphTaskConfig.comment=Comments [TBT] +iped.engine.graph.GraphTaskConfig.defaultBusinessEntity=Default Business Entity [TBT] +iped.engine.graph.GraphTaskConfig.defaultEntity=Default Entity [TBT] +iped.engine.graph.GraphTaskConfig.defaultPersonEntity=Default Person Entity [TBT] +iped.engine.graph.GraphTaskConfig.defaultRelationship=Default relationship [TBT] +iped.engine.graph.GraphTaskConfig.detectPhonesOnOtherMimes=Detect phone number on other mimetype files [TBT] +iped.engine.graph.GraphTaskConfig.entities=Entities [TBT] +iped.engine.task.HTMLReportTask=HTML Report Generation [TBT] +iped.engine.config.HtmlReportTaskConfig=HTML generation parameters [TBT] +iped.engine.config.HtmlReportTaskConfig.EnableThumbsGallery=Enable thumbs gallery [TBT] +iped.engine.config.HtmlReportTaskConfig.ThumbSize=Thumb size [TBT] +iped.engine.config.HtmlReportTaskConfig.Examiner=Examiner name [TBT] +iped.engine.config.HtmlReportTaskConfig.Report=Exame ID [TBT] +iped.engine.config.HtmlReportTaskConfig.RecordDate=Record date [TBT] +iped.engine.config.HtmlReportTaskConfig.EnableImageThumbs=Enable image thumbs [TBT] +iped.engine.config.HtmlReportTaskConfig.ThumbsPerPage=Thumbs per page [TBT] +iped.engine.config.HtmlReportTaskConfig.ItemsPerPage=Items per page [TBT] +iped.engine.config.HtmlReportTaskConfig.Title=Report Title [TBT] +iped.engine.config.HtmlReportTaskConfig.ReportDate=Report date [TBT] +iped.engine.config.HtmlReportTaskConfig.Material=Material ID [TBT] +iped.engine.config.HtmlReportTaskConfig.EnableVideoThumbs=Enable video thumbs [TBT] +iped.engine.config.HtmlReportTaskConfig.RequestDoc=Request document ID [TBT] +iped.engine.config.HtmlReportTaskConfig.ExaminerID=Examiner ID [TBT] +iped.engine.config.HtmlReportTaskConfig.Requester=Requester Name [TBT] +iped.engine.config.HtmlReportTaskConfig.RequestDate=Request Date [TBT] +iped.engine.config.HtmlReportTaskConfig.VideoStripeWidth=Video stripe width [TBT] +iped.engine.config.HtmlReportTaskConfig.Header=Report header [TBT] +iped.engine.config.HtmlReportTaskConfig.Investigation=Investigation name [TBT] +iped.engine.config.HtmlReportTaskConfig.FramesPerStripe=Video frames per stripe [TBT] +iped.engine.config.HtmlReportTaskConfig.Record=Request document ID [TBT] +iped.engine.config.HtmlReportTaskConfig.EnableCategoriesList=Enable categories list [TBT] +iped.engine.task.ParsingTask=Content parsing [TBT] +iped.engine.task.HashTask=Hash Calculation Task [TBT] +iped.engine.task.HashTask.tooltip=Hash Calculation Task [TBT] +iped.engine.config.HashTaskConfig=Hash configurations [TBT] +iped.engine.config.HashTaskConfig.tooltip=Configure algorithms used to calculate item hashes [TBT] +iped.engine.config.HashTaskConfig.hashes=Algorithms [TBT] +iped.engine.config.HashTaskConfig.hashes.tooltip=Algorithms used to calculate item hashes [TBT] +iped.engine.task.SignatureTask=Mime-type identification [TBT] +iped.engine.task.SignatureTask.tooltip=Mime-type identification based on FreeDesktop specification.
(https://specifications.freedesktop.org/shared-mime-info-spec/latest/ar01s02.html). [TBT] +iped.engine.config.SignatureConfig=Mime-type identification rules [TBT] +iped.engine.config.SignatureConfig.tooltip=Mime-type identification rules based on FreeDesktop specification.
(https://specifications.freedesktop.org/shared-mime-info-spec/latest/ar01s02.html). [TBT] +iped.engine.config.CategoryConfig=Categorization configuration based on mime-types [TBT] +iped.engine.config.CategoryConfig.tooltip=Specify which items are to be classified in each category based on their mime-types. Use drag and drop operations. [TBT] +iped.engine.task.SetCategoryTask=Item categorization [TBT] +iped.engine.task.HashDBLookupTask=Known hash database matching [TBT] +iped.engine.task.HashDBLookupTask.tooltip=Populates item with properties from known hashes database. [TBT] +iped.engine.task.DuplicateTask=Duplicate finding [TBT] +iped.engine.task.DuplicateTask.tooltip=Correlates duplicate items in the case based on their hash [TBT] +iped.engine.task.transcript.AudioTranscriptTask=Audio Transcription [TBT] +iped.engine.config.AudioTranscriptConfig=Audio Transcription Parameters [TBT] +iped.engine.config.AudioTranscriptConfig.implementationClass=Implementation class [TBT] +iped.engine.config.AudioTranscriptConfig.implementationClass.tooltip=Full name of java class that will execute the audio transcription algorithm. [TBT] +iped.engine.config.AudioTranscriptConfig.language=Language [TBT] +iped.engine.config.AudioTranscriptConfig.convertCommand=Conversion to WAV command [TBT] +iped.engine.config.AudioTranscriptConfig.mimesToProcess=Mime-types to process [TBT] +iped.engine.config.AudioTranscriptConfig.timeout=Transcription timeout [TBT] +iped.engine.config.AudioTranscriptConfig.minWordScore=Minimum word score [TBT] +iped.engine.config.AudioTranscriptConfig.serviceRegion=Service Region [TBT] +iped.engine.config.AudioTranscriptConfig.maxConcurrentRequests=Maximum concurrent requests [TBT] +iped.engine.config.AudioTranscriptConfig.requestIntervalMillis=Request interval (ms) [TBT] +iped.engine.config.AudioTranscriptConfig.googleModel=Google model [TBT] +iped.engine.task.video.VideoThumbTask=Video thumb creation [TBT] +iped.engine.task.video.VideoThumbTask.tooltip=Video thumb creation [TBT] +iped.engine.config.VideoThumbsConfig=Video Thumb parameters [TBT] +iped.engine.config.VideoThumbsConfig.tooltip=Thumb parameters [TBT] +iped.engine.config.VideoThumbsConfig.Layout=Layout [TBT] +iped.engine.config.VideoThumbsConfig.Timeouts=Timeouts [TBT] +iped.engine.config.VideoThumbsConfig.Verbose=Verbose [TBT] +iped.engine.config.VideoThumbsConfig.GalleryThumbs=Gallery thumbs [TBT] +iped.engine.config.VideoThumbsConfig.enableVideoThumbsSubitems=Enable subitems [TBT] +iped.engine.config.VideoThumbsConfig.enableVideoThumbsOriginalDimension=Enable original dimension [TBT] +iped.engine.config.VideoThumbsConfig.maxDimensionSize=Max dimension size [TBT] +iped.engine.task.QRCodeTask=QRCode extraction [TBT] +iped.engine.task.regex.RegexTask=Regular Expression matches extraction [TBT] +iped.engine.config.RegexTaskConfig=Regular expressions [TBT] +iped.engine.config.RegexTaskConfig.tooltip=Regular expressions [TBT] +iped.engine.config.RegexTaskConfig.formatMatches=Format matches [TBT] +iped.engine.config.RegexTaskConfig.formatMatches.tooltip=Format matches [TBT] +iped.engine.task.LanguageDetectTask=Language detection [TBT] +iped.engine.task.LanguageDetectTask.tooltip=Detects items content language [TBT] +iped.engine.task.NamedEntityTask=Named entity detection [TBT] +iped.engine.task.NamedEntityTask.tooltip=Detects named entities in item content [TBT] +iped.engine.config.NamedEntityTaskConfig=Named entity parameters [TBT] +iped.engine.config.NamedEntityTaskConfig.NERImpl=Implementation class [TBT] +iped.engine.config.NamedEntityTaskConfig.langModel_0=Language model [TBT] +iped.engine.config.NamedEntityTaskConfig.minLangScore=Minimum language score [TBT] +iped.engine.config.NamedEntityTaskConfig.mimeTypesToIgnore=Ignored mime-types [TBT] +iped.engine.config.NamedEntityTaskConfig.categoriesToIgnore=Ignored categories [TBT] +iped.engine.task.ExportFileTask=File export [TBT] +iped.engine.config.ExportByCategoriesConfig=Categories to export [TBT] +iped.engine.config.ExportByKeywordsConfig=Export based on keyword match [TBT] +iped.engine.task.EmbeddedDiskProcessTask=Embedded disk extraction [TBT] +iped.engine.task.MakePreviewTask=Preview creation task [TBT] +iped.engine.config.MakePreviewConfig=Mime types selection [TBT] +iped.engine.config.MakePreviewConfig.supportedMimeTypes=Supported mime types [TBT] +iped.engine.config.MakePreviewConfig.supportedMimeTypesWithLinks=Supported mime types with links [TBT] +iped.engine.task.DocThumbTask=Document thumbs creation [TBT] +iped.engine.config.DocThumbTaskConfig=Thumbs config [TBT] +iped.engine.config.DocThumbTaskConfig.pdfThumbs=PDF thumbs [TBT] +iped.engine.config.DocThumbTaskConfig.libreOfficeThumbs=Libre Office Thumbs [TBT] +iped.engine.config.DocThumbTaskConfig.pdfTimeout=PDF thumb creation timeout [TBT] +iped.engine.config.DocThumbTaskConfig.libreOfficeTimeout=Libre Office thumb creation timeout [TBT] +iped.engine.config.DocThumbTaskConfig.timeoutIncPerMB=Timeout increment per item size (MB) [TBT] +iped.engine.config.DocThumbTaskConfig.thumbSize=Thumb size [TBT] +iped.engine.config.DocThumbTaskConfig.maxPdfExternalMemory=Maximun PDF external memory [TBT] +iped.engine.task.die.DIETask=Explicit image detection [TBT] +iped.engine.task.die.DIETask.tooltip=Attributes nudity scores to images content [TBT] +iped.engine.task.similarity.ImageSimilarityTask=Image characteristic vector extraction [TBT] +iped.engine.task.similarity.ImageSimilarityTask.tooltip=Extracts characteristic vector from images to use in similar image searches [TBT] +iped.engine.task.PhotoDNATask=Photo DNA calculation [TBT] +iped.engine.config.PhotoDNAConfig=Photo DNA calculation parameters [TBT] +iped.engine.config.PhotoDNAConfig.computeFromThumbnail=Compute from thumbnail [TBT] +iped.engine.config.PhotoDNAConfig.minFileSize=Minimum file size [TBT] +iped.engine.config.PhotoDNAConfig.skipHashDBFiles=Ignores files found in hash database [TBT] +iped.engine.task.PhotoDNALookup=Photo DNA database match [TBT] +iped.engine.task.PhotoDNALookup.tooltip=Extracts properties from database based on Photo DNA value [TBT] +iped.engine.config.PhotoDNALookupConfig=Database lookup parameters [TBT] +iped.engine.config.PhotoDNALookupConfig.statusHashDBFilter=Hash status filter [TBT] +iped.engine.config.PhotoDNALookupConfig.maxSimilarityDistance=Maximum similarity distance [TBT] +iped.engine.config.PhotoDNALookupConfig.searchRotatedAndFlipped=Search for rotated or flipped image [TBT] +iped.engine.task.carver.LedCarveTask=Carve items based on LED database [TBT] +iped.engine.task.carver.LedCarveTask.tooltip=Carve items based on first 64K bytes hash match information found in LED database [TBT] +iped.engine.task.carver.CarverTask=Carve items [TBT] +iped.engine.task.carver.CarverTask.tooltip=Carve items based on customized carvers [TBT] +iped.engine.task.carver.KnownMetCarveTask=Carve Emule knownmet files [TBT] +iped.engine.task.carver.KnownMetCarveTask.tooltip=Carve Emule knownmet files [TBT] +iped.engine.task.FragmentLargeBinaryTask=Fragments large binary files [TBT] +iped.engine.config.SplitLargeBinaryConfig=Fragmentation parameters [TBT] +iped.engine.config.SplitLargeBinaryConfig.minItemSizeToFragment=Minimum size to fragment [TBT] +iped.engine.config.SplitLargeBinaryConfig.itemFragmentSize=Fragment size [TBT] +iped.engine.config.SplitLargeBinaryConfig.fragmentOverlapSize=Fragment overlap size [TBT] +iped.engine.task.EntropyTask=Entropy calculation [TBT] +iped.engine.task.EntropyTask.tooltip=Item entropy calculation [TBT] +iped.engine.task.MinIOTask=MinIO [TBT] +iped.engine.config.MinIOConfig=MinIO configuration [TBT] +iped.engine.config.MinIOConfig.host=Host IP address [TBT] +iped.engine.config.MinIOConfig.port=Host TCP port [TBT] +iped.engine.config.MinIOConfig.zipFilesMaxSize=Maximum size of zip files [TBT] +iped.engine.config.MinIOConfig.updateRefsToMinIO=Update references to MinIO [TBT] +iped.engine.config.MinIOConfig.timeOut=Timeout [TBT] +iped.engine.config.MinIOConfig.retries=Number of retries [TBT] +iped.engine.task.index.ElasticSearchIndexTask=Elastic search integration [TBT] +iped.engine.config.ElasticSearchTaskConfig=Elastic Seach parameters [TBT] +iped.engine.config.ElasticSearchTaskConfig.host=Server Host IP Address [TBT] +iped.engine.config.ElasticSearchTaskConfig.port=Server Host Port [TBT] +iped.engine.config.ElasticSearchTaskConfig.protocol=Server Host Protocol [TBT] +iped.engine.config.ElasticSearchTaskConfig.index.number_of_shards=Number of shards [TBT] +iped.engine.config.ElasticSearchTaskConfig.index.number_of_replicas=Number of replicas [TBT] +iped.engine.config.ElasticSearchTaskConfig.min_bulk_size=Minimum bulk size [TBT] +iped.engine.config.ElasticSearchTaskConfig.min_bulk_items=Minimum bulk items [TBT] +iped.engine.config.ElasticSearchTaskConfig.max_async_requests=Maximum asynchronous requests [TBT] +iped.engine.config.ElasticSearchTaskConfig.timeout_millis=Timeout (ms) [TBT] +iped.engine.config.ElasticSearchTaskConfig.connect_timeout_millis=Connection timeout [TBT] +iped.engine.config.ElasticSearchTaskConfig.index.mapping.total_fields.limit=Maximum number of fields [TBT] +iped.engine.config.ElasticSearchTaskConfig.useCustomAnalyser=Use custom analyser [TBT] +iped.engine.config.ElasticSearchTaskConfig.validateSSL=Validate SSL connection [TBT] +iped.engine.config.ElasticSearchTaskConfig.useTermVector=Use term vector [TBT] +iped.engine.task.index.IndexTask=Indexing [TBT] +iped.engine.task.index.IndexTask.tooltip=Lucene indexing of items content and metadata. [TBT] +iped.engine.config.IndexTaskConfig=Indexing parameters [TBT] +iped.engine.config.IndexTaskConfig.indexUnallocated=Index unallocated space [TBT] +iped.engine.config.IndexTaskConfig.convertCharsToLowerCase=Convert characters to lower case [TBT] +iped.engine.config.IndexTaskConfig.convertCharsToAscii=Convert characters to ASCII [TBT] +iped.engine.config.IndexTaskConfig.extraCharsToIndex=Additional characters to index [TBT] +iped.engine.config.IndexTaskConfig.filterNonLatinChars=Filter non latin characters [TBT] +iped.engine.config.IndexTaskConfig.textSplitSize=Text split size [TBT] +iped.engine.config.IndexTaskConfig.useNIOFSDirectory=Use NIO file system [TBT] +iped.engine.config.IndexTaskConfig.forceMerge=Force merge [TBT] +iped.engine.config.IndexTaskConfig.storeTermVectors=Store term vectors [TBT] +iped.engine.config.IndexTaskConfig.maxTokenLength=Maximum token length [TBT] +iped.engine.config.IndexTaskConfig.commitIntervalSeconds=Index commit interval [TBT] +iped.engine.graph.GraphTask=Graph creation [TBT] +iped.engine.task.ExportCSVTask=Export properties to CSV [TBT] +iped.engine.task.ExportCSVTask.tooltip=Export properties to CSV file [TBT] +iped.engine.config.CategoryToExpandConfig=Categories to expand [TBT] +iped.engine.config.CategoryToExpandConfig.tooltip=Categories to expand subitems including them on the parsing queue. [TBT] +iped.engine.config.ParsingTaskConfig=General parsing parameters [TBT] +iped.engine.config.ParsingTaskConfig.enableExternalParsing=Enable external parsing [TBT] +iped.engine.config.ParsingTaskConfig.numExternalParsers=Number of external parser processes [TBT] +iped.engine.config.ParsingTaskConfig.externalParsingMaxMem=Maximum memory per external parser process [TBT] +iped.engine.config.ParsingTaskConfig.parseUnknownFiles=Parse unknown files [TBT] +iped.engine.config.ParsingTaskConfig.parseCorruptedFiles=Parse corrupted files [TBT] +iped.engine.config.ParsingTaskConfig.timeOut=Item parsing timeout [TBT] +iped.engine.config.ParsingTaskConfig.timeOutPerMB=Item parsing timeout increment per MB [TBT] +iped.engine.config.ParsingTaskConfig.minRawStringSize=Minimum raw string size [TBT] +iped.engine.config.ParsingTaskConfig.phoneParsersToUse=Phone parsers to use [TBT] +iped.engine.config.ParsingTaskConfig.sortPDFChars=Sort PDF characters [TBT] +iped.engine.config.ParsingTaskConfig.processImagesInPDFs=Process images in PDFs [TBT] +iped.engine.config.ParsingTaskConfig.storeTextCacheOnDisk=Store text cache on disk [TBT] +iped.engine.config.OCRConfig=OCR parsing [TBT] +iped.engine.config.OCRConfig.enableOCR=Enable OCR [TBT] +iped.engine.config.OCRConfig.OCRLanguage=OCR Language [TBT] +iped.engine.config.OCRConfig.pageSegMode=Page segmentation mode [TBT] +iped.engine.config.OCRConfig.minFileSize2OCR=Minimum image file size to process OCR [TBT] +iped.engine.config.OCRConfig.pdfToImgResolution=PDF to Image resolution [TBT] +iped.engine.config.OCRConfig.maxPDFTextSize2OCR=Maximum PDF text size to OCR [TBT] +iped.engine.config.OCRConfig.pdfToImgLib=PDF to image library [TBT] +iped.engine.config.OCRConfig.externalPdfToImgConv=External PDF to image conversion [TBT] +iped.engine.config.OCRConfig.externalConvMaxMem=Maximum memory for external PDF conversion [TBT] +iped.engine.config.OCRConfig.processNonStandard=Process non standard [TBT] +iped.engine.config.OCRConfig.maxConvImageSize=Maximum conversion image size [TBT] +iped.engine.config.ParsersConfig=Specific Parsers [TBT] +iped.engine.config.ExternalParsersConfig=External parsers [TBT] +iped.engine.config.FileSystemConfig=Evidence options [TBT] +iped.engine.config.FileSystemConfig.robustImageReading=Robust image reading [TBT] +iped.engine.config.FileSystemConfig.numImageReaders=Number of readers [TBT] +iped.engine.config.FileSystemConfig.addUnallocated=Process unallocated space [TBT] +iped.engine.config.FileSystemConfig.addFileSlacks=Process file slack space [TBT] +iped.engine.config.FileSystemConfig.minOrphanSizeToIgnore=Minimun orphan files not to ignore [TBT] +iped.engine.config.FileSystemConfig.unallocatedFragSize=Size of unallocated space fragments [TBT] +iped.engine.config.FileSystemConfig.ignoreHardLinks=Ignore Hard Links [TBT] +iped.engine.config.FileSystemConfig.skipFolderRegex=Skip folders that matches regex [TBT] +iped.engine.task.SkipCommitedTask=Skip commited task [TBT] +iped.engine.task.SkipCommitedTask.tooltip=Skip commited task [TBT] +iped.engine.task.TempFileTask=Temporary file task [TBT] +iped.engine.task.TempFileTask.tooltip=Creates local temporary file to avoid repetitive network, decompression and slow source commands. [TBT] +iped.engine.task.SetTypeTask=Mimetype classification [TBT] +iped.engine.task.SetTypeTask.tooltip=Item classification based on its mime-type. [TBT] +iped.engine.task.IgnoreHardLinkTask=Ignore hard link references [TBT] +iped.engine.task.IgnoreHardLinkTask.tooltip=Ignores content processing of hard link references. [TBT] +iped.engine.task.RefineCategoryTask=Refine categories [TBT] +iped.engine.task.RefineCategoryTask.tooltip=Refines the categorization of found items. [TBT] +iped.engine.task.PythonTask.FaceRecognitionTask.py=Face recognition task [TBT] +iped.engine.config.DefaultTaskPropertiesConfig=Face recognition [TBT] +iped.engine.config.DefaultTaskPropertiesConfig.maxResolution=Max. resolution [TBT] +iped.engine.config.DefaultTaskPropertiesConfig.faceDetectionModel=Face detection model [TBT] +iped.engine.config.DefaultTaskPropertiesConfig.upSampling=Up Sampling [TBT] \ No newline at end of file diff --git a/iped-app/resources/localization/iped-engine-messages_es_AR.properties b/iped-app/resources/localization/iped-engine-messages_es_AR.properties index 1b71b6b7f6..b9425e8b02 100644 --- a/iped-app/resources/localization/iped-engine-messages_es_AR.properties +++ b/iped-app/resources/localization/iped-engine-messages_es_AR.properties @@ -123,3 +123,245 @@ GraphAnalysis.LinksEmails=Correos electrónicos GraphAnalysis.LinksInstantMessages=Mensajes instantáneos GraphAnalysis.LinksWireless=Redes inalámbricas GraphAnalysis.LinksDocuments=Documentos +iped.engine.task.ImageThumbTask=Image thumbs creation [TBT] +iped.engine.config.ImageThumbTaskConfig=Thumbs parameters [TBT] +iped.engine.config.ImageThumbTaskConfig.imgConvTimeoutPerMB=Timeout per MB [TBT] +iped.engine.config.ImageThumbTaskConfig.imgConvTimeout=Total timeout [TBT] +iped.engine.config.ImageThumbTaskConfig.lowResDensity=Low resolution density [TBT] +iped.engine.config.ImageThumbTaskConfig.highResDensity=High resolution density [TBT] +iped.engine.config.ImageThumbTaskConfig.maxMPixelsInMemory=Max memory used (MB) [TBT] +iped.engine.config.ImageThumbTaskConfig.logGalleryRendering=Log gallery rendering [TBT] +iped.engine.config.ImageThumbTaskConfig.imgThumbSize=Image thumb size [TBT] +iped.engine.config.ImageThumbTaskConfig.externalConversionTool=External conversion tool [TBT] +iped.engine.config.ImageThumbTaskConfig.enableExternalConv=Enable external conversion [TBT] +iped.engine.config.ImageThumbTaskConfig.extractThumb=Extract thumb [TBT] +iped.engine.config.ImageThumbTaskConfig.galleryThreads=Number of gallery threads [TBT] +iped.engine.graph.GraphTaskConfig=Graph creation [TBT] +iped.engine.graph.GraphTaskConfig.comment=Comments [TBT] +iped.engine.graph.GraphTaskConfig.defaultBusinessEntity=Default Business Entity [TBT] +iped.engine.graph.GraphTaskConfig.defaultEntity=Default Entity [TBT] +iped.engine.graph.GraphTaskConfig.defaultPersonEntity=Default Person Entity [TBT] +iped.engine.graph.GraphTaskConfig.defaultRelationship=Default relationship [TBT] +iped.engine.graph.GraphTaskConfig.detectPhonesOnOtherMimes=Detect phone number on other mimetype files [TBT] +iped.engine.graph.GraphTaskConfig.entities=Entities [TBT] +iped.engine.task.HTMLReportTask=HTML Report Generation [TBT] +iped.engine.config.HtmlReportTaskConfig=HTML generation parameters [TBT] +iped.engine.config.HtmlReportTaskConfig.EnableThumbsGallery=Enable thumbs gallery [TBT] +iped.engine.config.HtmlReportTaskConfig.ThumbSize=Thumb size [TBT] +iped.engine.config.HtmlReportTaskConfig.Examiner=Examiner name [TBT] +iped.engine.config.HtmlReportTaskConfig.Report=Exame ID [TBT] +iped.engine.config.HtmlReportTaskConfig.RecordDate=Record date [TBT] +iped.engine.config.HtmlReportTaskConfig.EnableImageThumbs=Enable image thumbs [TBT] +iped.engine.config.HtmlReportTaskConfig.ThumbsPerPage=Thumbs per page [TBT] +iped.engine.config.HtmlReportTaskConfig.ItemsPerPage=Items per page [TBT] +iped.engine.config.HtmlReportTaskConfig.Title=Report Title [TBT] +iped.engine.config.HtmlReportTaskConfig.ReportDate=Report date [TBT] +iped.engine.config.HtmlReportTaskConfig.Material=Material ID [TBT] +iped.engine.config.HtmlReportTaskConfig.EnableVideoThumbs=Enable video thumbs [TBT] +iped.engine.config.HtmlReportTaskConfig.RequestDoc=Request document ID [TBT] +iped.engine.config.HtmlReportTaskConfig.ExaminerID=Examiner ID [TBT] +iped.engine.config.HtmlReportTaskConfig.Requester=Requester Name [TBT] +iped.engine.config.HtmlReportTaskConfig.RequestDate=Request Date [TBT] +iped.engine.config.HtmlReportTaskConfig.VideoStripeWidth=Video stripe width [TBT] +iped.engine.config.HtmlReportTaskConfig.Header=Report header [TBT] +iped.engine.config.HtmlReportTaskConfig.Investigation=Investigation name [TBT] +iped.engine.config.HtmlReportTaskConfig.FramesPerStripe=Video frames per stripe [TBT] +iped.engine.config.HtmlReportTaskConfig.Record=Request document ID [TBT] +iped.engine.config.HtmlReportTaskConfig.EnableCategoriesList=Enable categories list [TBT] +iped.engine.task.ParsingTask=Content parsing [TBT] +iped.engine.task.HashTask=Hash Calculation Task [TBT] +iped.engine.task.HashTask.tooltip=Hash Calculation Task [TBT] +iped.engine.config.HashTaskConfig=Hash configurations [TBT] +iped.engine.config.HashTaskConfig.tooltip=Configure algorithms used to calculate item hashes [TBT] +iped.engine.config.HashTaskConfig.hashes=Algorithms [TBT] +iped.engine.config.HashTaskConfig.hashes.tooltip=Algorithms used to calculate item hashes [TBT] +iped.engine.task.SignatureTask=Mime-type identification [TBT] +iped.engine.task.SignatureTask.tooltip=Mime-type identification based on FreeDesktop specification.
(https://specifications.freedesktop.org/shared-mime-info-spec/latest/ar01s02.html). [TBT] +iped.engine.config.SignatureConfig=Mime-type identification rules [TBT] +iped.engine.config.SignatureConfig.tooltip=Mime-type identification rules based on FreeDesktop specification.
(https://specifications.freedesktop.org/shared-mime-info-spec/latest/ar01s02.html). [TBT] +iped.engine.config.CategoryConfig=Categorization configuration based on mime-types [TBT] +iped.engine.config.CategoryConfig.tooltip=Specify which items are to be classified in each category based on their mime-types. Use drag and drop operations. [TBT] +iped.engine.task.SetCategoryTask=Item categorization [TBT] +iped.engine.task.HashDBLookupTask=Known hash database matching [TBT] +iped.engine.task.HashDBLookupTask.tooltip=Populates item with properties from known hashes database. [TBT] +iped.engine.task.DuplicateTask=Duplicate finding [TBT] +iped.engine.task.DuplicateTask.tooltip=Correlates duplicate items in the case based on their hash [TBT] +iped.engine.task.transcript.AudioTranscriptTask=Audio Transcription [TBT] +iped.engine.config.AudioTranscriptConfig=Audio Transcription Parameters [TBT] +iped.engine.config.AudioTranscriptConfig.implementationClass=Implementation class [TBT] +iped.engine.config.AudioTranscriptConfig.implementationClass.tooltip=Full name of java class that will execute the audio transcription algorithm. [TBT] +iped.engine.config.AudioTranscriptConfig.language=Language [TBT] +iped.engine.config.AudioTranscriptConfig.convertCommand=Conversion to WAV command [TBT] +iped.engine.config.AudioTranscriptConfig.mimesToProcess=Mime-types to process [TBT] +iped.engine.config.AudioTranscriptConfig.timeout=Transcription timeout [TBT] +iped.engine.config.AudioTranscriptConfig.minWordScore=Minimum word score [TBT] +iped.engine.config.AudioTranscriptConfig.serviceRegion=Service Region [TBT] +iped.engine.config.AudioTranscriptConfig.maxConcurrentRequests=Maximum concurrent requests [TBT] +iped.engine.config.AudioTranscriptConfig.requestIntervalMillis=Request interval (ms) [TBT] +iped.engine.config.AudioTranscriptConfig.googleModel=Google model [TBT] +iped.engine.task.video.VideoThumbTask=Video thumb creation [TBT] +iped.engine.task.video.VideoThumbTask.tooltip=Video thumb creation [TBT] +iped.engine.config.VideoThumbsConfig=Video Thumb parameters [TBT] +iped.engine.config.VideoThumbsConfig.tooltip=Thumb parameters [TBT] +iped.engine.config.VideoThumbsConfig.Layout=Layout [TBT] +iped.engine.config.VideoThumbsConfig.Timeouts=Timeouts [TBT] +iped.engine.config.VideoThumbsConfig.Verbose=Verbose [TBT] +iped.engine.config.VideoThumbsConfig.GalleryThumbs=Gallery thumbs [TBT] +iped.engine.config.VideoThumbsConfig.enableVideoThumbsSubitems=Enable subitems [TBT] +iped.engine.config.VideoThumbsConfig.enableVideoThumbsOriginalDimension=Enable original dimension [TBT] +iped.engine.config.VideoThumbsConfig.maxDimensionSize=Max dimension size [TBT] +iped.engine.task.QRCodeTask=QRCode extraction [TBT] +iped.engine.task.regex.RegexTask=Regular Expression matches extraction [TBT] +iped.engine.config.RegexTaskConfig=Regular expressions [TBT] +iped.engine.config.RegexTaskConfig.tooltip=Regular expressions [TBT] +iped.engine.config.RegexTaskConfig.formatMatches=Format matches [TBT] +iped.engine.config.RegexTaskConfig.formatMatches.tooltip=Format matches [TBT] +iped.engine.task.LanguageDetectTask=Language detection [TBT] +iped.engine.task.LanguageDetectTask.tooltip=Detects items content language [TBT] +iped.engine.task.NamedEntityTask=Named entity detection [TBT] +iped.engine.task.NamedEntityTask.tooltip=Detects named entities in item content [TBT] +iped.engine.config.NamedEntityTaskConfig=Named entity parameters [TBT] +iped.engine.config.NamedEntityTaskConfig.NERImpl=Implementation class [TBT] +iped.engine.config.NamedEntityTaskConfig.langModel_0=Language model [TBT] +iped.engine.config.NamedEntityTaskConfig.minLangScore=Minimum language score [TBT] +iped.engine.config.NamedEntityTaskConfig.mimeTypesToIgnore=Ignored mime-types [TBT] +iped.engine.config.NamedEntityTaskConfig.categoriesToIgnore=Ignored categories [TBT] +iped.engine.task.ExportFileTask=File export [TBT] +iped.engine.config.ExportByCategoriesConfig=Categories to export [TBT] +iped.engine.config.ExportByKeywordsConfig=Export based on keyword match [TBT] +iped.engine.task.EmbeddedDiskProcessTask=Embedded disk extraction [TBT] +iped.engine.task.MakePreviewTask=Preview creation task [TBT] +iped.engine.config.MakePreviewConfig=Mime types selection [TBT] +iped.engine.config.MakePreviewConfig.supportedMimeTypes=Supported mime types [TBT] +iped.engine.config.MakePreviewConfig.supportedMimeTypesWithLinks=Supported mime types with links [TBT] +iped.engine.task.DocThumbTask=Document thumbs creation [TBT] +iped.engine.config.DocThumbTaskConfig=Thumbs config [TBT] +iped.engine.config.DocThumbTaskConfig.pdfThumbs=PDF thumbs [TBT] +iped.engine.config.DocThumbTaskConfig.libreOfficeThumbs=Libre Office Thumbs [TBT] +iped.engine.config.DocThumbTaskConfig.pdfTimeout=PDF thumb creation timeout [TBT] +iped.engine.config.DocThumbTaskConfig.libreOfficeTimeout=Libre Office thumb creation timeout [TBT] +iped.engine.config.DocThumbTaskConfig.timeoutIncPerMB=Timeout increment per item size (MB) [TBT] +iped.engine.config.DocThumbTaskConfig.thumbSize=Thumb size [TBT] +iped.engine.config.DocThumbTaskConfig.maxPdfExternalMemory=Maximun PDF external memory [TBT] +iped.engine.task.die.DIETask=Explicit image detection [TBT] +iped.engine.task.die.DIETask.tooltip=Attributes nudity scores to images content [TBT] +iped.engine.task.similarity.ImageSimilarityTask=Image characteristic vector extraction [TBT] +iped.engine.task.similarity.ImageSimilarityTask.tooltip=Extracts characteristic vector from images to use in similar image searches [TBT] +iped.engine.task.PhotoDNATask=Photo DNA calculation [TBT] +iped.engine.config.PhotoDNAConfig=Photo DNA calculation parameters [TBT] +iped.engine.config.PhotoDNAConfig.computeFromThumbnail=Compute from thumbnail [TBT] +iped.engine.config.PhotoDNAConfig.minFileSize=Minimum file size [TBT] +iped.engine.config.PhotoDNAConfig.skipHashDBFiles=Ignores files found in hash database [TBT] +iped.engine.task.PhotoDNALookup=Photo DNA database match [TBT] +iped.engine.task.PhotoDNALookup.tooltip=Extracts properties from database based on Photo DNA value [TBT] +iped.engine.config.PhotoDNALookupConfig=Database lookup parameters [TBT] +iped.engine.config.PhotoDNALookupConfig.statusHashDBFilter=Hash status filter [TBT] +iped.engine.config.PhotoDNALookupConfig.maxSimilarityDistance=Maximum similarity distance [TBT] +iped.engine.config.PhotoDNALookupConfig.searchRotatedAndFlipped=Search for rotated or flipped image [TBT] +iped.engine.task.carver.LedCarveTask=Carve items based on LED database [TBT] +iped.engine.task.carver.LedCarveTask.tooltip=Carve items based on first 64K bytes hash match information found in LED database [TBT] +iped.engine.task.carver.CarverTask=Carve items [TBT] +iped.engine.task.carver.CarverTask.tooltip=Carve items based on customized carvers [TBT] +iped.engine.task.carver.KnownMetCarveTask=Carve Emule knownmet files [TBT] +iped.engine.task.carver.KnownMetCarveTask.tooltip=Carve Emule knownmet files [TBT] +iped.engine.task.FragmentLargeBinaryTask=Fragments large binary files [TBT] +iped.engine.config.SplitLargeBinaryConfig=Fragmentation parameters [TBT] +iped.engine.config.SplitLargeBinaryConfig.minItemSizeToFragment=Minimum size to fragment [TBT] +iped.engine.config.SplitLargeBinaryConfig.itemFragmentSize=Fragment size [TBT] +iped.engine.config.SplitLargeBinaryConfig.fragmentOverlapSize=Fragment overlap size [TBT] +iped.engine.task.EntropyTask=Entropy calculation [TBT] +iped.engine.task.EntropyTask.tooltip=Item entropy calculation [TBT] +iped.engine.task.MinIOTask=MinIO [TBT] +iped.engine.config.MinIOConfig=MinIO configuration [TBT] +iped.engine.config.MinIOConfig.host=Host IP address [TBT] +iped.engine.config.MinIOConfig.port=Host TCP port [TBT] +iped.engine.config.MinIOConfig.zipFilesMaxSize=Maximum size of zip files [TBT] +iped.engine.config.MinIOConfig.updateRefsToMinIO=Update references to MinIO [TBT] +iped.engine.config.MinIOConfig.timeOut=Timeout [TBT] +iped.engine.config.MinIOConfig.retries=Number of retries [TBT] +iped.engine.task.index.ElasticSearchIndexTask=Elastic search integration [TBT] +iped.engine.config.ElasticSearchTaskConfig=Elastic Seach parameters [TBT] +iped.engine.config.ElasticSearchTaskConfig.host=Server Host IP Address [TBT] +iped.engine.config.ElasticSearchTaskConfig.port=Server Host Port [TBT] +iped.engine.config.ElasticSearchTaskConfig.protocol=Server Host Protocol [TBT] +iped.engine.config.ElasticSearchTaskConfig.index.number_of_shards=Number of shards [TBT] +iped.engine.config.ElasticSearchTaskConfig.index.number_of_replicas=Number of replicas [TBT] +iped.engine.config.ElasticSearchTaskConfig.min_bulk_size=Minimum bulk size [TBT] +iped.engine.config.ElasticSearchTaskConfig.min_bulk_items=Minimum bulk items [TBT] +iped.engine.config.ElasticSearchTaskConfig.max_async_requests=Maximum asynchronous requests [TBT] +iped.engine.config.ElasticSearchTaskConfig.timeout_millis=Timeout (ms) [TBT] +iped.engine.config.ElasticSearchTaskConfig.connect_timeout_millis=Connection timeout [TBT] +iped.engine.config.ElasticSearchTaskConfig.index.mapping.total_fields.limit=Maximum number of fields [TBT] +iped.engine.config.ElasticSearchTaskConfig.useCustomAnalyser=Use custom analyser [TBT] +iped.engine.config.ElasticSearchTaskConfig.validateSSL=Validate SSL connection [TBT] +iped.engine.config.ElasticSearchTaskConfig.useTermVector=Use term vector [TBT] +iped.engine.task.index.IndexTask=Indexing [TBT] +iped.engine.task.index.IndexTask.tooltip=Lucene indexing of items content and metadata. [TBT] +iped.engine.config.IndexTaskConfig=Indexing parameters [TBT] +iped.engine.config.IndexTaskConfig.indexUnallocated=Index unallocated space [TBT] +iped.engine.config.IndexTaskConfig.convertCharsToLowerCase=Convert characters to lower case [TBT] +iped.engine.config.IndexTaskConfig.convertCharsToAscii=Convert characters to ASCII [TBT] +iped.engine.config.IndexTaskConfig.extraCharsToIndex=Additional characters to index [TBT] +iped.engine.config.IndexTaskConfig.filterNonLatinChars=Filter non latin characters [TBT] +iped.engine.config.IndexTaskConfig.textSplitSize=Text split size [TBT] +iped.engine.config.IndexTaskConfig.useNIOFSDirectory=Use NIO file system [TBT] +iped.engine.config.IndexTaskConfig.forceMerge=Force merge [TBT] +iped.engine.config.IndexTaskConfig.storeTermVectors=Store term vectors [TBT] +iped.engine.config.IndexTaskConfig.maxTokenLength=Maximum token length [TBT] +iped.engine.config.IndexTaskConfig.commitIntervalSeconds=Index commit interval [TBT] +iped.engine.graph.GraphTask=Graph creation [TBT] +iped.engine.task.ExportCSVTask=Export properties to CSV [TBT] +iped.engine.task.ExportCSVTask.tooltip=Export properties to CSV file [TBT] +iped.engine.config.CategoryToExpandConfig=Categories to expand [TBT] +iped.engine.config.CategoryToExpandConfig.tooltip=Categories to expand subitems including them on the parsing queue. [TBT] +iped.engine.config.ParsingTaskConfig=General parsing parameters [TBT] +iped.engine.config.ParsingTaskConfig.enableExternalParsing=Enable external parsing [TBT] +iped.engine.config.ParsingTaskConfig.numExternalParsers=Number of external parser processes [TBT] +iped.engine.config.ParsingTaskConfig.externalParsingMaxMem=Maximum memory per external parser process [TBT] +iped.engine.config.ParsingTaskConfig.parseUnknownFiles=Parse unknown files [TBT] +iped.engine.config.ParsingTaskConfig.parseCorruptedFiles=Parse corrupted files [TBT] +iped.engine.config.ParsingTaskConfig.timeOut=Item parsing timeout [TBT] +iped.engine.config.ParsingTaskConfig.timeOutPerMB=Item parsing timeout increment per MB [TBT] +iped.engine.config.ParsingTaskConfig.minRawStringSize=Minimum raw string size [TBT] +iped.engine.config.ParsingTaskConfig.phoneParsersToUse=Phone parsers to use [TBT] +iped.engine.config.ParsingTaskConfig.sortPDFChars=Sort PDF characters [TBT] +iped.engine.config.ParsingTaskConfig.processImagesInPDFs=Process images in PDFs [TBT] +iped.engine.config.ParsingTaskConfig.storeTextCacheOnDisk=Store text cache on disk [TBT] +iped.engine.config.OCRConfig=OCR parsing [TBT] +iped.engine.config.OCRConfig.enableOCR=Enable OCR [TBT] +iped.engine.config.OCRConfig.OCRLanguage=OCR Language [TBT] +iped.engine.config.OCRConfig.pageSegMode=Page segmentation mode [TBT] +iped.engine.config.OCRConfig.minFileSize2OCR=Minimum image file size to process OCR [TBT] +iped.engine.config.OCRConfig.pdfToImgResolution=PDF to Image resolution [TBT] +iped.engine.config.OCRConfig.maxPDFTextSize2OCR=Maximum PDF text size to OCR [TBT] +iped.engine.config.OCRConfig.pdfToImgLib=PDF to image library [TBT] +iped.engine.config.OCRConfig.externalPdfToImgConv=External PDF to image conversion [TBT] +iped.engine.config.OCRConfig.externalConvMaxMem=Maximum memory for external PDF conversion [TBT] +iped.engine.config.OCRConfig.processNonStandard=Process non standard [TBT] +iped.engine.config.OCRConfig.maxConvImageSize=Maximum conversion image size [TBT] +iped.engine.config.ParsersConfig=Specific Parsers [TBT] +iped.engine.config.ExternalParsersConfig=External parsers [TBT] +iped.engine.config.FileSystemConfig=Evidence options [TBT] +iped.engine.config.FileSystemConfig.robustImageReading=Robust image reading [TBT] +iped.engine.config.FileSystemConfig.numImageReaders=Number of readers [TBT] +iped.engine.config.FileSystemConfig.addUnallocated=Process unallocated space [TBT] +iped.engine.config.FileSystemConfig.addFileSlacks=Process file slack space [TBT] +iped.engine.config.FileSystemConfig.minOrphanSizeToIgnore=Minimun orphan files not to ignore [TBT] +iped.engine.config.FileSystemConfig.unallocatedFragSize=Size of unallocated space fragments [TBT] +iped.engine.config.FileSystemConfig.ignoreHardLinks=Ignore Hard Links [TBT] +iped.engine.config.FileSystemConfig.skipFolderRegex=Skip folders that matches regex [TBT] +iped.engine.task.SkipCommitedTask=Skip commited task [TBT] +iped.engine.task.SkipCommitedTask.tooltip=Skip commited task [TBT] +iped.engine.task.TempFileTask=Temporary file task [TBT] +iped.engine.task.TempFileTask.tooltip=Creates local temporary file to avoid repetitive network, decompression and slow source commands. [TBT] +iped.engine.task.SetTypeTask=Mimetype classification [TBT] +iped.engine.task.SetTypeTask.tooltip=Item classification based on its mime-type. [TBT] +iped.engine.task.IgnoreHardLinkTask=Ignore hard link references [TBT] +iped.engine.task.IgnoreHardLinkTask.tooltip=Ignores content processing of hard link references. [TBT] +iped.engine.task.RefineCategoryTask=Refine categories [TBT] +iped.engine.task.RefineCategoryTask.tooltip=Refines the categorization of found items. [TBT] +iped.engine.task.PythonTask.FaceRecognitionTask.py=Face recognition task [TBT] +iped.engine.config.DefaultTaskPropertiesConfig=Face recognition [TBT] +iped.engine.config.DefaultTaskPropertiesConfig.maxResolution=Max. resolution [TBT] +iped.engine.config.DefaultTaskPropertiesConfig.faceDetectionModel=Face detection model [TBT] +iped.engine.config.DefaultTaskPropertiesConfig.upSampling=Up Sampling [TBT] \ No newline at end of file diff --git a/iped-app/resources/localization/iped-engine-messages_fr_FR.properties b/iped-app/resources/localization/iped-engine-messages_fr_FR.properties index 901b91c370..42dd378769 100644 --- a/iped-app/resources/localization/iped-engine-messages_fr_FR.properties +++ b/iped-app/resources/localization/iped-engine-messages_fr_FR.properties @@ -123,3 +123,245 @@ GraphAnalysis.LinksEmails=E-mails GraphAnalysis.LinksInstantMessages=Messages instantannés GraphAnalysis.LinksWireless=Réseaux sans fils GraphAnalysis.LinksDocuments=Documents +iped.engine.task.ImageThumbTask=Image thumbs creation [TBT] +iped.engine.config.ImageThumbTaskConfig=Thumbs parameters [TBT] +iped.engine.config.ImageThumbTaskConfig.imgConvTimeoutPerMB=Timeout per MB [TBT] +iped.engine.config.ImageThumbTaskConfig.imgConvTimeout=Total timeout [TBT] +iped.engine.config.ImageThumbTaskConfig.lowResDensity=Low resolution density [TBT] +iped.engine.config.ImageThumbTaskConfig.highResDensity=High resolution density [TBT] +iped.engine.config.ImageThumbTaskConfig.maxMPixelsInMemory=Max memory used (MB) [TBT] +iped.engine.config.ImageThumbTaskConfig.logGalleryRendering=Log gallery rendering [TBT] +iped.engine.config.ImageThumbTaskConfig.imgThumbSize=Image thumb size [TBT] +iped.engine.config.ImageThumbTaskConfig.externalConversionTool=External conversion tool [TBT] +iped.engine.config.ImageThumbTaskConfig.enableExternalConv=Enable external conversion [TBT] +iped.engine.config.ImageThumbTaskConfig.extractThumb=Extract thumb [TBT] +iped.engine.config.ImageThumbTaskConfig.galleryThreads=Number of gallery threads [TBT] +iped.engine.graph.GraphTaskConfig=Graph creation [TBT] +iped.engine.graph.GraphTaskConfig.comment=Comments [TBT] +iped.engine.graph.GraphTaskConfig.defaultBusinessEntity=Default Business Entity [TBT] +iped.engine.graph.GraphTaskConfig.defaultEntity=Default Entity [TBT] +iped.engine.graph.GraphTaskConfig.defaultPersonEntity=Default Person Entity [TBT] +iped.engine.graph.GraphTaskConfig.defaultRelationship=Default relationship [TBT] +iped.engine.graph.GraphTaskConfig.detectPhonesOnOtherMimes=Detect phone number on other mimetype files [TBT] +iped.engine.graph.GraphTaskConfig.entities=Entities [TBT] +iped.engine.task.HTMLReportTask=HTML Report Generation [TBT] +iped.engine.config.HtmlReportTaskConfig=HTML generation parameters [TBT] +iped.engine.config.HtmlReportTaskConfig.EnableThumbsGallery=Enable thumbs gallery [TBT] +iped.engine.config.HtmlReportTaskConfig.ThumbSize=Thumb size [TBT] +iped.engine.config.HtmlReportTaskConfig.Examiner=Examiner name [TBT] +iped.engine.config.HtmlReportTaskConfig.Report=Exame ID [TBT] +iped.engine.config.HtmlReportTaskConfig.RecordDate=Record date [TBT] +iped.engine.config.HtmlReportTaskConfig.EnableImageThumbs=Enable image thumbs [TBT] +iped.engine.config.HtmlReportTaskConfig.ThumbsPerPage=Thumbs per page [TBT] +iped.engine.config.HtmlReportTaskConfig.ItemsPerPage=Items per page [TBT] +iped.engine.config.HtmlReportTaskConfig.Title=Report Title [TBT] +iped.engine.config.HtmlReportTaskConfig.ReportDate=Report date [TBT] +iped.engine.config.HtmlReportTaskConfig.Material=Material ID [TBT] +iped.engine.config.HtmlReportTaskConfig.EnableVideoThumbs=Enable video thumbs [TBT] +iped.engine.config.HtmlReportTaskConfig.RequestDoc=Request document ID [TBT] +iped.engine.config.HtmlReportTaskConfig.ExaminerID=Examiner ID [TBT] +iped.engine.config.HtmlReportTaskConfig.Requester=Requester Name [TBT] +iped.engine.config.HtmlReportTaskConfig.RequestDate=Request Date [TBT] +iped.engine.config.HtmlReportTaskConfig.VideoStripeWidth=Video stripe width [TBT] +iped.engine.config.HtmlReportTaskConfig.Header=Report header [TBT] +iped.engine.config.HtmlReportTaskConfig.Investigation=Investigation name [TBT] +iped.engine.config.HtmlReportTaskConfig.FramesPerStripe=Video frames per stripe [TBT] +iped.engine.config.HtmlReportTaskConfig.Record=Request document ID [TBT] +iped.engine.config.HtmlReportTaskConfig.EnableCategoriesList=Enable categories list [TBT] +iped.engine.task.ParsingTask=Content parsing [TBT] +iped.engine.task.HashTask=Hash Calculation Task [TBT] +iped.engine.task.HashTask.tooltip=Hash Calculation Task [TBT] +iped.engine.config.HashTaskConfig=Hash configurations [TBT] +iped.engine.config.HashTaskConfig.tooltip=Configure algorithms used to calculate item hashes [TBT] +iped.engine.config.HashTaskConfig.hashes=Algorithms [TBT] +iped.engine.config.HashTaskConfig.hashes.tooltip=Algorithms used to calculate item hashes [TBT] +iped.engine.task.SignatureTask=Mime-type identification [TBT] +iped.engine.task.SignatureTask.tooltip=Mime-type identification based on FreeDesktop specification.
(https://specifications.freedesktop.org/shared-mime-info-spec/latest/ar01s02.html). [TBT] +iped.engine.config.SignatureConfig=Mime-type identification rules [TBT] +iped.engine.config.SignatureConfig.tooltip=Mime-type identification rules based on FreeDesktop specification.
(https://specifications.freedesktop.org/shared-mime-info-spec/latest/ar01s02.html). [TBT] +iped.engine.config.CategoryConfig=Categorization configuration based on mime-types [TBT] +iped.engine.config.CategoryConfig.tooltip=Specify which items are to be classified in each category based on their mime-types. Use drag and drop operations. [TBT] +iped.engine.task.SetCategoryTask=Item categorization [TBT] +iped.engine.task.HashDBLookupTask=Known hash database matching [TBT] +iped.engine.task.HashDBLookupTask.tooltip=Populates item with properties from known hashes database. [TBT] +iped.engine.task.DuplicateTask=Duplicate finding [TBT] +iped.engine.task.DuplicateTask.tooltip=Correlates duplicate items in the case based on their hash [TBT] +iped.engine.task.transcript.AudioTranscriptTask=Audio Transcription [TBT] +iped.engine.config.AudioTranscriptConfig=Audio Transcription Parameters [TBT] +iped.engine.config.AudioTranscriptConfig.implementationClass=Implementation class [TBT] +iped.engine.config.AudioTranscriptConfig.implementationClass.tooltip=Full name of java class that will execute the audio transcription algorithm. [TBT] +iped.engine.config.AudioTranscriptConfig.language=Language [TBT] +iped.engine.config.AudioTranscriptConfig.convertCommand=Conversion to WAV command [TBT] +iped.engine.config.AudioTranscriptConfig.mimesToProcess=Mime-types to process [TBT] +iped.engine.config.AudioTranscriptConfig.timeout=Transcription timeout [TBT] +iped.engine.config.AudioTranscriptConfig.minWordScore=Minimum word score [TBT] +iped.engine.config.AudioTranscriptConfig.serviceRegion=Service Region [TBT] +iped.engine.config.AudioTranscriptConfig.maxConcurrentRequests=Maximum concurrent requests [TBT] +iped.engine.config.AudioTranscriptConfig.requestIntervalMillis=Request interval (ms) [TBT] +iped.engine.config.AudioTranscriptConfig.googleModel=Google model [TBT] +iped.engine.task.video.VideoThumbTask=Video thumb creation [TBT] +iped.engine.task.video.VideoThumbTask.tooltip=Video thumb creation [TBT] +iped.engine.config.VideoThumbsConfig=Video Thumb parameters [TBT] +iped.engine.config.VideoThumbsConfig.tooltip=Thumb parameters [TBT] +iped.engine.config.VideoThumbsConfig.Layout=Layout [TBT] +iped.engine.config.VideoThumbsConfig.Timeouts=Timeouts [TBT] +iped.engine.config.VideoThumbsConfig.Verbose=Verbose [TBT] +iped.engine.config.VideoThumbsConfig.GalleryThumbs=Gallery thumbs [TBT] +iped.engine.config.VideoThumbsConfig.enableVideoThumbsSubitems=Enable subitems [TBT] +iped.engine.config.VideoThumbsConfig.enableVideoThumbsOriginalDimension=Enable original dimension [TBT] +iped.engine.config.VideoThumbsConfig.maxDimensionSize=Max dimension size [TBT] +iped.engine.task.QRCodeTask=QRCode extraction [TBT] +iped.engine.task.regex.RegexTask=Regular Expression matches extraction [TBT] +iped.engine.config.RegexTaskConfig=Regular expressions [TBT] +iped.engine.config.RegexTaskConfig.tooltip=Regular expressions [TBT] +iped.engine.config.RegexTaskConfig.formatMatches=Format matches [TBT] +iped.engine.config.RegexTaskConfig.formatMatches.tooltip=Format matches [TBT] +iped.engine.task.LanguageDetectTask=Language detection [TBT] +iped.engine.task.LanguageDetectTask.tooltip=Detects items content language [TBT] +iped.engine.task.NamedEntityTask=Named entity detection [TBT] +iped.engine.task.NamedEntityTask.tooltip=Detects named entities in item content [TBT] +iped.engine.config.NamedEntityTaskConfig=Named entity parameters [TBT] +iped.engine.config.NamedEntityTaskConfig.NERImpl=Implementation class [TBT] +iped.engine.config.NamedEntityTaskConfig.langModel_0=Language model [TBT] +iped.engine.config.NamedEntityTaskConfig.minLangScore=Minimum language score [TBT] +iped.engine.config.NamedEntityTaskConfig.mimeTypesToIgnore=Ignored mime-types [TBT] +iped.engine.config.NamedEntityTaskConfig.categoriesToIgnore=Ignored categories [TBT] +iped.engine.task.ExportFileTask=File export [TBT] +iped.engine.config.ExportByCategoriesConfig=Categories to export [TBT] +iped.engine.config.ExportByKeywordsConfig=Export based on keyword match [TBT] +iped.engine.task.EmbeddedDiskProcessTask=Embedded disk extraction [TBT] +iped.engine.task.MakePreviewTask=Preview creation task [TBT] +iped.engine.config.MakePreviewConfig=Mime types selection [TBT] +iped.engine.config.MakePreviewConfig.supportedMimeTypes=Supported mime types [TBT] +iped.engine.config.MakePreviewConfig.supportedMimeTypesWithLinks=Supported mime types with links [TBT] +iped.engine.task.DocThumbTask=Document thumbs creation [TBT] +iped.engine.config.DocThumbTaskConfig=Thumbs config [TBT] +iped.engine.config.DocThumbTaskConfig.pdfThumbs=PDF thumbs [TBT] +iped.engine.config.DocThumbTaskConfig.libreOfficeThumbs=Libre Office Thumbs [TBT] +iped.engine.config.DocThumbTaskConfig.pdfTimeout=PDF thumb creation timeout [TBT] +iped.engine.config.DocThumbTaskConfig.libreOfficeTimeout=Libre Office thumb creation timeout [TBT] +iped.engine.config.DocThumbTaskConfig.timeoutIncPerMB=Timeout increment per item size (MB) [TBT] +iped.engine.config.DocThumbTaskConfig.thumbSize=Thumb size [TBT] +iped.engine.config.DocThumbTaskConfig.maxPdfExternalMemory=Maximun PDF external memory [TBT] +iped.engine.task.die.DIETask=Explicit image detection [TBT] +iped.engine.task.die.DIETask.tooltip=Attributes nudity scores to images content [TBT] +iped.engine.task.similarity.ImageSimilarityTask=Image characteristic vector extraction [TBT] +iped.engine.task.similarity.ImageSimilarityTask.tooltip=Extracts characteristic vector from images to use in similar image searches [TBT] +iped.engine.task.PhotoDNATask=Photo DNA calculation [TBT] +iped.engine.config.PhotoDNAConfig=Photo DNA calculation parameters [TBT] +iped.engine.config.PhotoDNAConfig.computeFromThumbnail=Compute from thumbnail [TBT] +iped.engine.config.PhotoDNAConfig.minFileSize=Minimum file size [TBT] +iped.engine.config.PhotoDNAConfig.skipHashDBFiles=Ignores files found in hash database [TBT] +iped.engine.task.PhotoDNALookup=Photo DNA database match [TBT] +iped.engine.task.PhotoDNALookup.tooltip=Extracts properties from database based on Photo DNA value [TBT] +iped.engine.config.PhotoDNALookupConfig=Database lookup parameters [TBT] +iped.engine.config.PhotoDNALookupConfig.statusHashDBFilter=Hash status filter [TBT] +iped.engine.config.PhotoDNALookupConfig.maxSimilarityDistance=Maximum similarity distance [TBT] +iped.engine.config.PhotoDNALookupConfig.searchRotatedAndFlipped=Search for rotated or flipped image [TBT] +iped.engine.task.carver.LedCarveTask=Carve items based on LED database [TBT] +iped.engine.task.carver.LedCarveTask.tooltip=Carve items based on first 64K bytes hash match information found in LED database [TBT] +iped.engine.task.carver.CarverTask=Carve items [TBT] +iped.engine.task.carver.CarverTask.tooltip=Carve items based on customized carvers [TBT] +iped.engine.task.carver.KnownMetCarveTask=Carve Emule knownmet files [TBT] +iped.engine.task.carver.KnownMetCarveTask.tooltip=Carve Emule knownmet files [TBT] +iped.engine.task.FragmentLargeBinaryTask=Fragments large binary files [TBT] +iped.engine.config.SplitLargeBinaryConfig=Fragmentation parameters [TBT] +iped.engine.config.SplitLargeBinaryConfig.minItemSizeToFragment=Minimum size to fragment [TBT] +iped.engine.config.SplitLargeBinaryConfig.itemFragmentSize=Fragment size [TBT] +iped.engine.config.SplitLargeBinaryConfig.fragmentOverlapSize=Fragment overlap size [TBT] +iped.engine.task.EntropyTask=Entropy calculation [TBT] +iped.engine.task.EntropyTask.tooltip=Item entropy calculation [TBT] +iped.engine.task.MinIOTask=MinIO [TBT] +iped.engine.config.MinIOConfig=MinIO configuration [TBT] +iped.engine.config.MinIOConfig.host=Host IP address [TBT] +iped.engine.config.MinIOConfig.port=Host TCP port [TBT] +iped.engine.config.MinIOConfig.zipFilesMaxSize=Maximum size of zip files [TBT] +iped.engine.config.MinIOConfig.updateRefsToMinIO=Update references to MinIO [TBT] +iped.engine.config.MinIOConfig.timeOut=Timeout [TBT] +iped.engine.config.MinIOConfig.retries=Number of retries [TBT] +iped.engine.task.index.ElasticSearchIndexTask=Elastic search integration [TBT] +iped.engine.config.ElasticSearchTaskConfig=Elastic Seach parameters [TBT] +iped.engine.config.ElasticSearchTaskConfig.host=Server Host IP Address [TBT] +iped.engine.config.ElasticSearchTaskConfig.port=Server Host Port [TBT] +iped.engine.config.ElasticSearchTaskConfig.protocol=Server Host Protocol [TBT] +iped.engine.config.ElasticSearchTaskConfig.index.number_of_shards=Number of shards [TBT] +iped.engine.config.ElasticSearchTaskConfig.index.number_of_replicas=Number of replicas [TBT] +iped.engine.config.ElasticSearchTaskConfig.min_bulk_size=Minimum bulk size [TBT] +iped.engine.config.ElasticSearchTaskConfig.min_bulk_items=Minimum bulk items [TBT] +iped.engine.config.ElasticSearchTaskConfig.max_async_requests=Maximum asynchronous requests [TBT] +iped.engine.config.ElasticSearchTaskConfig.timeout_millis=Timeout (ms) [TBT] +iped.engine.config.ElasticSearchTaskConfig.connect_timeout_millis=Connection timeout [TBT] +iped.engine.config.ElasticSearchTaskConfig.index.mapping.total_fields.limit=Maximum number of fields [TBT] +iped.engine.config.ElasticSearchTaskConfig.useCustomAnalyser=Use custom analyser [TBT] +iped.engine.config.ElasticSearchTaskConfig.validateSSL=Validate SSL connection [TBT] +iped.engine.config.ElasticSearchTaskConfig.useTermVector=Use term vector [TBT] +iped.engine.task.index.IndexTask=Indexing [TBT] +iped.engine.task.index.IndexTask.tooltip=Lucene indexing of items content and metadata. [TBT] +iped.engine.config.IndexTaskConfig=Indexing parameters [TBT] +iped.engine.config.IndexTaskConfig.indexUnallocated=Index unallocated space [TBT] +iped.engine.config.IndexTaskConfig.convertCharsToLowerCase=Convert characters to lower case [TBT] +iped.engine.config.IndexTaskConfig.convertCharsToAscii=Convert characters to ASCII [TBT] +iped.engine.config.IndexTaskConfig.extraCharsToIndex=Additional characters to index [TBT] +iped.engine.config.IndexTaskConfig.filterNonLatinChars=Filter non latin characters [TBT] +iped.engine.config.IndexTaskConfig.textSplitSize=Text split size [TBT] +iped.engine.config.IndexTaskConfig.useNIOFSDirectory=Use NIO file system [TBT] +iped.engine.config.IndexTaskConfig.forceMerge=Force merge [TBT] +iped.engine.config.IndexTaskConfig.storeTermVectors=Store term vectors [TBT] +iped.engine.config.IndexTaskConfig.maxTokenLength=Maximum token length [TBT] +iped.engine.config.IndexTaskConfig.commitIntervalSeconds=Index commit interval [TBT] +iped.engine.graph.GraphTask=Graph creation [TBT] +iped.engine.task.ExportCSVTask=Export properties to CSV [TBT] +iped.engine.task.ExportCSVTask.tooltip=Export properties to CSV file [TBT] +iped.engine.config.CategoryToExpandConfig=Categories to expand [TBT] +iped.engine.config.CategoryToExpandConfig.tooltip=Categories to expand subitems including them on the parsing queue. [TBT] +iped.engine.config.ParsingTaskConfig=General parsing parameters [TBT] +iped.engine.config.ParsingTaskConfig.enableExternalParsing=Enable external parsing [TBT] +iped.engine.config.ParsingTaskConfig.numExternalParsers=Number of external parser processes [TBT] +iped.engine.config.ParsingTaskConfig.externalParsingMaxMem=Maximum memory per external parser process [TBT] +iped.engine.config.ParsingTaskConfig.parseUnknownFiles=Parse unknown files [TBT] +iped.engine.config.ParsingTaskConfig.parseCorruptedFiles=Parse corrupted files [TBT] +iped.engine.config.ParsingTaskConfig.timeOut=Item parsing timeout [TBT] +iped.engine.config.ParsingTaskConfig.timeOutPerMB=Item parsing timeout increment per MB [TBT] +iped.engine.config.ParsingTaskConfig.minRawStringSize=Minimum raw string size [TBT] +iped.engine.config.ParsingTaskConfig.phoneParsersToUse=Phone parsers to use [TBT] +iped.engine.config.ParsingTaskConfig.sortPDFChars=Sort PDF characters [TBT] +iped.engine.config.ParsingTaskConfig.processImagesInPDFs=Process images in PDFs [TBT] +iped.engine.config.ParsingTaskConfig.storeTextCacheOnDisk=Store text cache on disk [TBT] +iped.engine.config.OCRConfig=OCR parsing [TBT] +iped.engine.config.OCRConfig.enableOCR=Enable OCR [TBT] +iped.engine.config.OCRConfig.OCRLanguage=OCR Language [TBT] +iped.engine.config.OCRConfig.pageSegMode=Page segmentation mode [TBT] +iped.engine.config.OCRConfig.minFileSize2OCR=Minimum image file size to process OCR [TBT] +iped.engine.config.OCRConfig.pdfToImgResolution=PDF to Image resolution [TBT] +iped.engine.config.OCRConfig.maxPDFTextSize2OCR=Maximum PDF text size to OCR [TBT] +iped.engine.config.OCRConfig.pdfToImgLib=PDF to image library [TBT] +iped.engine.config.OCRConfig.externalPdfToImgConv=External PDF to image conversion [TBT] +iped.engine.config.OCRConfig.externalConvMaxMem=Maximum memory for external PDF conversion [TBT] +iped.engine.config.OCRConfig.processNonStandard=Process non standard [TBT] +iped.engine.config.OCRConfig.maxConvImageSize=Maximum conversion image size [TBT] +iped.engine.config.ParsersConfig=Specific Parsers [TBT] +iped.engine.config.ExternalParsersConfig=External parsers [TBT] +iped.engine.config.FileSystemConfig=Evidence options [TBT] +iped.engine.config.FileSystemConfig.robustImageReading=Robust image reading [TBT] +iped.engine.config.FileSystemConfig.numImageReaders=Number of readers [TBT] +iped.engine.config.FileSystemConfig.addUnallocated=Process unallocated space [TBT] +iped.engine.config.FileSystemConfig.addFileSlacks=Process file slack space [TBT] +iped.engine.config.FileSystemConfig.minOrphanSizeToIgnore=Minimun orphan files not to ignore [TBT] +iped.engine.config.FileSystemConfig.unallocatedFragSize=Size of unallocated space fragments [TBT] +iped.engine.config.FileSystemConfig.ignoreHardLinks=Ignore Hard Links [TBT] +iped.engine.config.FileSystemConfig.skipFolderRegex=Skip folders that matches regex [TBT] +iped.engine.task.SkipCommitedTask=Skip commited task [TBT] +iped.engine.task.SkipCommitedTask.tooltip=Skip commited task [TBT] +iped.engine.task.TempFileTask=Temporary file task [TBT] +iped.engine.task.TempFileTask.tooltip=Creates local temporary file to avoid repetitive network, decompression and slow source commands. [TBT] +iped.engine.task.SetTypeTask=Mimetype classification [TBT] +iped.engine.task.SetTypeTask.tooltip=Item classification based on its mime-type. [TBT] +iped.engine.task.IgnoreHardLinkTask=Ignore hard link references [TBT] +iped.engine.task.IgnoreHardLinkTask.tooltip=Ignores content processing of hard link references. [TBT] +iped.engine.task.RefineCategoryTask=Refine categories [TBT] +iped.engine.task.RefineCategoryTask.tooltip=Refines the categorization of found items. [TBT] +iped.engine.task.PythonTask.FaceRecognitionTask.py=Face recognition task [TBT] +iped.engine.config.DefaultTaskPropertiesConfig=Face recognition [TBT] +iped.engine.config.DefaultTaskPropertiesConfig.maxResolution=Max. resolution [TBT] +iped.engine.config.DefaultTaskPropertiesConfig.faceDetectionModel=Face detection model [TBT] +iped.engine.config.DefaultTaskPropertiesConfig.upSampling=Up Sampling [TBT] \ No newline at end of file diff --git a/iped-app/resources/localization/iped-engine-messages_it_IT.properties b/iped-app/resources/localization/iped-engine-messages_it_IT.properties index d14873ab81..dab9faf9e2 100644 --- a/iped-app/resources/localization/iped-engine-messages_it_IT.properties +++ b/iped-app/resources/localization/iped-engine-messages_it_IT.properties @@ -123,3 +123,245 @@ GraphAnalysis.LinksEmails=E-mail GraphAnalysis.LinksInstantMessages=Messaggi Istantanei GraphAnalysis.LinksWireless=Reti Wireless GraphAnalysis.LinksDocuments=Documenti +iped.engine.task.ImageThumbTask=Image thumbs creation [TBT] +iped.engine.config.ImageThumbTaskConfig=Thumbs parameters [TBT] +iped.engine.config.ImageThumbTaskConfig.imgConvTimeoutPerMB=Timeout per MB [TBT] +iped.engine.config.ImageThumbTaskConfig.imgConvTimeout=Total timeout [TBT] +iped.engine.config.ImageThumbTaskConfig.lowResDensity=Low resolution density [TBT] +iped.engine.config.ImageThumbTaskConfig.highResDensity=High resolution density [TBT] +iped.engine.config.ImageThumbTaskConfig.maxMPixelsInMemory=Max memory used (MB) [TBT] +iped.engine.config.ImageThumbTaskConfig.logGalleryRendering=Log gallery rendering [TBT] +iped.engine.config.ImageThumbTaskConfig.imgThumbSize=Image thumb size [TBT] +iped.engine.config.ImageThumbTaskConfig.externalConversionTool=External conversion tool [TBT] +iped.engine.config.ImageThumbTaskConfig.enableExternalConv=Enable external conversion [TBT] +iped.engine.config.ImageThumbTaskConfig.extractThumb=Extract thumb [TBT] +iped.engine.config.ImageThumbTaskConfig.galleryThreads=Number of gallery threads [TBT] +iped.engine.graph.GraphTaskConfig=Graph creation [TBT] +iped.engine.graph.GraphTaskConfig.comment=Comments [TBT] +iped.engine.graph.GraphTaskConfig.defaultBusinessEntity=Default Business Entity [TBT] +iped.engine.graph.GraphTaskConfig.defaultEntity=Default Entity [TBT] +iped.engine.graph.GraphTaskConfig.defaultPersonEntity=Default Person Entity [TBT] +iped.engine.graph.GraphTaskConfig.defaultRelationship=Default relationship [TBT] +iped.engine.graph.GraphTaskConfig.detectPhonesOnOtherMimes=Detect phone number on other mimetype files [TBT] +iped.engine.graph.GraphTaskConfig.entities=Entities [TBT] +iped.engine.task.HTMLReportTask=HTML Report Generation [TBT] +iped.engine.config.HtmlReportTaskConfig=HTML generation parameters [TBT] +iped.engine.config.HtmlReportTaskConfig.EnableThumbsGallery=Enable thumbs gallery [TBT] +iped.engine.config.HtmlReportTaskConfig.ThumbSize=Thumb size [TBT] +iped.engine.config.HtmlReportTaskConfig.Examiner=Examiner name [TBT] +iped.engine.config.HtmlReportTaskConfig.Report=Exame ID [TBT] +iped.engine.config.HtmlReportTaskConfig.RecordDate=Record date [TBT] +iped.engine.config.HtmlReportTaskConfig.EnableImageThumbs=Enable image thumbs [TBT] +iped.engine.config.HtmlReportTaskConfig.ThumbsPerPage=Thumbs per page [TBT] +iped.engine.config.HtmlReportTaskConfig.ItemsPerPage=Items per page [TBT] +iped.engine.config.HtmlReportTaskConfig.Title=Report Title [TBT] +iped.engine.config.HtmlReportTaskConfig.ReportDate=Report date [TBT] +iped.engine.config.HtmlReportTaskConfig.Material=Material ID [TBT] +iped.engine.config.HtmlReportTaskConfig.EnableVideoThumbs=Enable video thumbs [TBT] +iped.engine.config.HtmlReportTaskConfig.RequestDoc=Request document ID [TBT] +iped.engine.config.HtmlReportTaskConfig.ExaminerID=Examiner ID [TBT] +iped.engine.config.HtmlReportTaskConfig.Requester=Requester Name [TBT] +iped.engine.config.HtmlReportTaskConfig.RequestDate=Request Date [TBT] +iped.engine.config.HtmlReportTaskConfig.VideoStripeWidth=Video stripe width [TBT] +iped.engine.config.HtmlReportTaskConfig.Header=Report header [TBT] +iped.engine.config.HtmlReportTaskConfig.Investigation=Investigation name [TBT] +iped.engine.config.HtmlReportTaskConfig.FramesPerStripe=Video frames per stripe [TBT] +iped.engine.config.HtmlReportTaskConfig.Record=Request document ID [TBT] +iped.engine.config.HtmlReportTaskConfig.EnableCategoriesList=Enable categories list [TBT] +iped.engine.task.ParsingTask=Content parsing [TBT] +iped.engine.task.HashTask=Hash Calculation Task [TBT] +iped.engine.task.HashTask.tooltip=Hash Calculation Task [TBT] +iped.engine.config.HashTaskConfig=Hash configurations [TBT] +iped.engine.config.HashTaskConfig.tooltip=Configure algorithms used to calculate item hashes [TBT] +iped.engine.config.HashTaskConfig.hashes=Algorithms [TBT] +iped.engine.config.HashTaskConfig.hashes.tooltip=Algorithms used to calculate item hashes [TBT] +iped.engine.task.SignatureTask=Mime-type identification [TBT] +iped.engine.task.SignatureTask.tooltip=Mime-type identification based on FreeDesktop specification.
(https://specifications.freedesktop.org/shared-mime-info-spec/latest/ar01s02.html). [TBT] +iped.engine.config.SignatureConfig=Mime-type identification rules [TBT] +iped.engine.config.SignatureConfig.tooltip=Mime-type identification rules based on FreeDesktop specification.
(https://specifications.freedesktop.org/shared-mime-info-spec/latest/ar01s02.html). [TBT] +iped.engine.config.CategoryConfig=Categorization configuration based on mime-types [TBT] +iped.engine.config.CategoryConfig.tooltip=Specify which items are to be classified in each category based on their mime-types. Use drag and drop operations. [TBT] +iped.engine.task.SetCategoryTask=Item categorization [TBT] +iped.engine.task.HashDBLookupTask=Known hash database matching [TBT] +iped.engine.task.HashDBLookupTask.tooltip=Populates item with properties from known hashes database. [TBT] +iped.engine.task.DuplicateTask=Duplicate finding [TBT] +iped.engine.task.DuplicateTask.tooltip=Correlates duplicate items in the case based on their hash [TBT] +iped.engine.task.transcript.AudioTranscriptTask=Audio Transcription [TBT] +iped.engine.config.AudioTranscriptConfig=Audio Transcription Parameters [TBT] +iped.engine.config.AudioTranscriptConfig.implementationClass=Implementation class [TBT] +iped.engine.config.AudioTranscriptConfig.implementationClass.tooltip=Full name of java class that will execute the audio transcription algorithm. [TBT] +iped.engine.config.AudioTranscriptConfig.language=Language [TBT] +iped.engine.config.AudioTranscriptConfig.convertCommand=Conversion to WAV command [TBT] +iped.engine.config.AudioTranscriptConfig.mimesToProcess=Mime-types to process [TBT] +iped.engine.config.AudioTranscriptConfig.timeout=Transcription timeout [TBT] +iped.engine.config.AudioTranscriptConfig.minWordScore=Minimum word score [TBT] +iped.engine.config.AudioTranscriptConfig.serviceRegion=Service Region [TBT] +iped.engine.config.AudioTranscriptConfig.maxConcurrentRequests=Maximum concurrent requests [TBT] +iped.engine.config.AudioTranscriptConfig.requestIntervalMillis=Request interval (ms) [TBT] +iped.engine.config.AudioTranscriptConfig.googleModel=Google model [TBT] +iped.engine.task.video.VideoThumbTask=Video thumb creation [TBT] +iped.engine.task.video.VideoThumbTask.tooltip=Video thumb creation [TBT] +iped.engine.config.VideoThumbsConfig=Video Thumb parameters [TBT] +iped.engine.config.VideoThumbsConfig.tooltip=Thumb parameters [TBT] +iped.engine.config.VideoThumbsConfig.Layout=Layout [TBT] +iped.engine.config.VideoThumbsConfig.Timeouts=Timeouts [TBT] +iped.engine.config.VideoThumbsConfig.Verbose=Verbose [TBT] +iped.engine.config.VideoThumbsConfig.GalleryThumbs=Gallery thumbs [TBT] +iped.engine.config.VideoThumbsConfig.enableVideoThumbsSubitems=Enable subitems [TBT] +iped.engine.config.VideoThumbsConfig.enableVideoThumbsOriginalDimension=Enable original dimension [TBT] +iped.engine.config.VideoThumbsConfig.maxDimensionSize=Max dimension size [TBT] +iped.engine.task.QRCodeTask=QRCode extraction [TBT] +iped.engine.task.regex.RegexTask=Regular Expression matches extraction [TBT] +iped.engine.config.RegexTaskConfig=Regular expressions [TBT] +iped.engine.config.RegexTaskConfig.tooltip=Regular expressions [TBT] +iped.engine.config.RegexTaskConfig.formatMatches=Format matches [TBT] +iped.engine.config.RegexTaskConfig.formatMatches.tooltip=Format matches [TBT] +iped.engine.task.LanguageDetectTask=Language detection [TBT] +iped.engine.task.LanguageDetectTask.tooltip=Detects items content language [TBT] +iped.engine.task.NamedEntityTask=Named entity detection [TBT] +iped.engine.task.NamedEntityTask.tooltip=Detects named entities in item content [TBT] +iped.engine.config.NamedEntityTaskConfig=Named entity parameters [TBT] +iped.engine.config.NamedEntityTaskConfig.NERImpl=Implementation class [TBT] +iped.engine.config.NamedEntityTaskConfig.langModel_0=Language model [TBT] +iped.engine.config.NamedEntityTaskConfig.minLangScore=Minimum language score [TBT] +iped.engine.config.NamedEntityTaskConfig.mimeTypesToIgnore=Ignored mime-types [TBT] +iped.engine.config.NamedEntityTaskConfig.categoriesToIgnore=Ignored categories [TBT] +iped.engine.task.ExportFileTask=File export [TBT] +iped.engine.config.ExportByCategoriesConfig=Categories to export [TBT] +iped.engine.config.ExportByKeywordsConfig=Export based on keyword match [TBT] +iped.engine.task.EmbeddedDiskProcessTask=Embedded disk extraction [TBT] +iped.engine.task.MakePreviewTask=Preview creation task [TBT] +iped.engine.config.MakePreviewConfig=Mime types selection [TBT] +iped.engine.config.MakePreviewConfig.supportedMimeTypes=Supported mime types [TBT] +iped.engine.config.MakePreviewConfig.supportedMimeTypesWithLinks=Supported mime types with links [TBT] +iped.engine.task.DocThumbTask=Document thumbs creation [TBT] +iped.engine.config.DocThumbTaskConfig=Thumbs config [TBT] +iped.engine.config.DocThumbTaskConfig.pdfThumbs=PDF thumbs [TBT] +iped.engine.config.DocThumbTaskConfig.libreOfficeThumbs=Libre Office Thumbs [TBT] +iped.engine.config.DocThumbTaskConfig.pdfTimeout=PDF thumb creation timeout [TBT] +iped.engine.config.DocThumbTaskConfig.libreOfficeTimeout=Libre Office thumb creation timeout [TBT] +iped.engine.config.DocThumbTaskConfig.timeoutIncPerMB=Timeout increment per item size (MB) [TBT] +iped.engine.config.DocThumbTaskConfig.thumbSize=Thumb size [TBT] +iped.engine.config.DocThumbTaskConfig.maxPdfExternalMemory=Maximun PDF external memory [TBT] +iped.engine.task.die.DIETask=Explicit image detection [TBT] +iped.engine.task.die.DIETask.tooltip=Attributes nudity scores to images content [TBT] +iped.engine.task.similarity.ImageSimilarityTask=Image characteristic vector extraction [TBT] +iped.engine.task.similarity.ImageSimilarityTask.tooltip=Extracts characteristic vector from images to use in similar image searches [TBT] +iped.engine.task.PhotoDNATask=Photo DNA calculation [TBT] +iped.engine.config.PhotoDNAConfig=Photo DNA calculation parameters [TBT] +iped.engine.config.PhotoDNAConfig.computeFromThumbnail=Compute from thumbnail [TBT] +iped.engine.config.PhotoDNAConfig.minFileSize=Minimum file size [TBT] +iped.engine.config.PhotoDNAConfig.skipHashDBFiles=Ignores files found in hash database [TBT] +iped.engine.task.PhotoDNALookup=Photo DNA database match [TBT] +iped.engine.task.PhotoDNALookup.tooltip=Extracts properties from database based on Photo DNA value [TBT] +iped.engine.config.PhotoDNALookupConfig=Database lookup parameters [TBT] +iped.engine.config.PhotoDNALookupConfig.statusHashDBFilter=Hash status filter [TBT] +iped.engine.config.PhotoDNALookupConfig.maxSimilarityDistance=Maximum similarity distance [TBT] +iped.engine.config.PhotoDNALookupConfig.searchRotatedAndFlipped=Search for rotated or flipped image [TBT] +iped.engine.task.carver.LedCarveTask=Carve items based on LED database [TBT] +iped.engine.task.carver.LedCarveTask.tooltip=Carve items based on first 64K bytes hash match information found in LED database [TBT] +iped.engine.task.carver.CarverTask=Carve items [TBT] +iped.engine.task.carver.CarverTask.tooltip=Carve items based on customized carvers [TBT] +iped.engine.task.carver.KnownMetCarveTask=Carve Emule knownmet files [TBT] +iped.engine.task.carver.KnownMetCarveTask.tooltip=Carve Emule knownmet files [TBT] +iped.engine.task.FragmentLargeBinaryTask=Fragments large binary files [TBT] +iped.engine.config.SplitLargeBinaryConfig=Fragmentation parameters [TBT] +iped.engine.config.SplitLargeBinaryConfig.minItemSizeToFragment=Minimum size to fragment [TBT] +iped.engine.config.SplitLargeBinaryConfig.itemFragmentSize=Fragment size [TBT] +iped.engine.config.SplitLargeBinaryConfig.fragmentOverlapSize=Fragment overlap size [TBT] +iped.engine.task.EntropyTask=Entropy calculation [TBT] +iped.engine.task.EntropyTask.tooltip=Item entropy calculation [TBT] +iped.engine.task.MinIOTask=MinIO [TBT] +iped.engine.config.MinIOConfig=MinIO configuration [TBT] +iped.engine.config.MinIOConfig.host=Host IP address [TBT] +iped.engine.config.MinIOConfig.port=Host TCP port [TBT] +iped.engine.config.MinIOConfig.zipFilesMaxSize=Maximum size of zip files [TBT] +iped.engine.config.MinIOConfig.updateRefsToMinIO=Update references to MinIO [TBT] +iped.engine.config.MinIOConfig.timeOut=Timeout [TBT] +iped.engine.config.MinIOConfig.retries=Number of retries [TBT] +iped.engine.task.index.ElasticSearchIndexTask=Elastic search integration [TBT] +iped.engine.config.ElasticSearchTaskConfig=Elastic Seach parameters [TBT] +iped.engine.config.ElasticSearchTaskConfig.host=Server Host IP Address [TBT] +iped.engine.config.ElasticSearchTaskConfig.port=Server Host Port [TBT] +iped.engine.config.ElasticSearchTaskConfig.protocol=Server Host Protocol [TBT] +iped.engine.config.ElasticSearchTaskConfig.index.number_of_shards=Number of shards [TBT] +iped.engine.config.ElasticSearchTaskConfig.index.number_of_replicas=Number of replicas [TBT] +iped.engine.config.ElasticSearchTaskConfig.min_bulk_size=Minimum bulk size [TBT] +iped.engine.config.ElasticSearchTaskConfig.min_bulk_items=Minimum bulk items [TBT] +iped.engine.config.ElasticSearchTaskConfig.max_async_requests=Maximum asynchronous requests [TBT] +iped.engine.config.ElasticSearchTaskConfig.timeout_millis=Timeout (ms) [TBT] +iped.engine.config.ElasticSearchTaskConfig.connect_timeout_millis=Connection timeout [TBT] +iped.engine.config.ElasticSearchTaskConfig.index.mapping.total_fields.limit=Maximum number of fields [TBT] +iped.engine.config.ElasticSearchTaskConfig.useCustomAnalyser=Use custom analyser [TBT] +iped.engine.config.ElasticSearchTaskConfig.validateSSL=Validate SSL connection [TBT] +iped.engine.config.ElasticSearchTaskConfig.useTermVector=Use term vector [TBT] +iped.engine.task.index.IndexTask=Indexing [TBT] +iped.engine.task.index.IndexTask.tooltip=Lucene indexing of items content and metadata. [TBT] +iped.engine.config.IndexTaskConfig=Indexing parameters [TBT] +iped.engine.config.IndexTaskConfig.indexUnallocated=Index unallocated space [TBT] +iped.engine.config.IndexTaskConfig.convertCharsToLowerCase=Convert characters to lower case [TBT] +iped.engine.config.IndexTaskConfig.convertCharsToAscii=Convert characters to ASCII [TBT] +iped.engine.config.IndexTaskConfig.extraCharsToIndex=Additional characters to index [TBT] +iped.engine.config.IndexTaskConfig.filterNonLatinChars=Filter non latin characters [TBT] +iped.engine.config.IndexTaskConfig.textSplitSize=Text split size [TBT] +iped.engine.config.IndexTaskConfig.useNIOFSDirectory=Use NIO file system [TBT] +iped.engine.config.IndexTaskConfig.forceMerge=Force merge [TBT] +iped.engine.config.IndexTaskConfig.storeTermVectors=Store term vectors [TBT] +iped.engine.config.IndexTaskConfig.maxTokenLength=Maximum token length [TBT] +iped.engine.config.IndexTaskConfig.commitIntervalSeconds=Index commit interval [TBT] +iped.engine.graph.GraphTask=Graph creation [TBT] +iped.engine.task.ExportCSVTask=Export properties to CSV [TBT] +iped.engine.task.ExportCSVTask.tooltip=Export properties to CSV file [TBT] +iped.engine.config.CategoryToExpandConfig=Categories to expand [TBT] +iped.engine.config.CategoryToExpandConfig.tooltip=Categories to expand subitems including them on the parsing queue. [TBT] +iped.engine.config.ParsingTaskConfig=General parsing parameters [TBT] +iped.engine.config.ParsingTaskConfig.enableExternalParsing=Enable external parsing [TBT] +iped.engine.config.ParsingTaskConfig.numExternalParsers=Number of external parser processes [TBT] +iped.engine.config.ParsingTaskConfig.externalParsingMaxMem=Maximum memory per external parser process [TBT] +iped.engine.config.ParsingTaskConfig.parseUnknownFiles=Parse unknown files [TBT] +iped.engine.config.ParsingTaskConfig.parseCorruptedFiles=Parse corrupted files [TBT] +iped.engine.config.ParsingTaskConfig.timeOut=Item parsing timeout [TBT] +iped.engine.config.ParsingTaskConfig.timeOutPerMB=Item parsing timeout increment per MB [TBT] +iped.engine.config.ParsingTaskConfig.minRawStringSize=Minimum raw string size [TBT] +iped.engine.config.ParsingTaskConfig.phoneParsersToUse=Phone parsers to use [TBT] +iped.engine.config.ParsingTaskConfig.sortPDFChars=Sort PDF characters [TBT] +iped.engine.config.ParsingTaskConfig.processImagesInPDFs=Process images in PDFs [TBT] +iped.engine.config.ParsingTaskConfig.storeTextCacheOnDisk=Store text cache on disk [TBT] +iped.engine.config.OCRConfig=OCR parsing [TBT] +iped.engine.config.OCRConfig.enableOCR=Enable OCR [TBT] +iped.engine.config.OCRConfig.OCRLanguage=OCR Language [TBT] +iped.engine.config.OCRConfig.pageSegMode=Page segmentation mode [TBT] +iped.engine.config.OCRConfig.minFileSize2OCR=Minimum image file size to process OCR [TBT] +iped.engine.config.OCRConfig.pdfToImgResolution=PDF to Image resolution [TBT] +iped.engine.config.OCRConfig.maxPDFTextSize2OCR=Maximum PDF text size to OCR [TBT] +iped.engine.config.OCRConfig.pdfToImgLib=PDF to image library [TBT] +iped.engine.config.OCRConfig.externalPdfToImgConv=External PDF to image conversion [TBT] +iped.engine.config.OCRConfig.externalConvMaxMem=Maximum memory for external PDF conversion [TBT] +iped.engine.config.OCRConfig.processNonStandard=Process non standard [TBT] +iped.engine.config.OCRConfig.maxConvImageSize=Maximum conversion image size [TBT] +iped.engine.config.ParsersConfig=Specific Parsers [TBT] +iped.engine.config.ExternalParsersConfig=External parsers [TBT] +iped.engine.config.FileSystemConfig=Evidence options [TBT] +iped.engine.config.FileSystemConfig.robustImageReading=Robust image reading [TBT] +iped.engine.config.FileSystemConfig.numImageReaders=Number of readers [TBT] +iped.engine.config.FileSystemConfig.addUnallocated=Process unallocated space [TBT] +iped.engine.config.FileSystemConfig.addFileSlacks=Process file slack space [TBT] +iped.engine.config.FileSystemConfig.minOrphanSizeToIgnore=Minimun orphan files not to ignore [TBT] +iped.engine.config.FileSystemConfig.unallocatedFragSize=Size of unallocated space fragments [TBT] +iped.engine.config.FileSystemConfig.ignoreHardLinks=Ignore Hard Links [TBT] +iped.engine.config.FileSystemConfig.skipFolderRegex=Skip folders that matches regex [TBT] +iped.engine.task.SkipCommitedTask=Skip commited task [TBT] +iped.engine.task.SkipCommitedTask.tooltip=Skip commited task [TBT] +iped.engine.task.TempFileTask=Temporary file task [TBT] +iped.engine.task.TempFileTask.tooltip=Creates local temporary file to avoid repetitive network, decompression and slow source commands. [TBT] +iped.engine.task.SetTypeTask=Mimetype classification [TBT] +iped.engine.task.SetTypeTask.tooltip=Item classification based on its mime-type. [TBT] +iped.engine.task.IgnoreHardLinkTask=Ignore hard link references [TBT] +iped.engine.task.IgnoreHardLinkTask.tooltip=Ignores content processing of hard link references. [TBT] +iped.engine.task.RefineCategoryTask=Refine categories [TBT] +iped.engine.task.RefineCategoryTask.tooltip=Refines the categorization of found items. [TBT] +iped.engine.task.PythonTask.FaceRecognitionTask.py=Face recognition task [TBT] +iped.engine.config.DefaultTaskPropertiesConfig=Face recognition [TBT] +iped.engine.config.DefaultTaskPropertiesConfig.maxResolution=Max. resolution [TBT] +iped.engine.config.DefaultTaskPropertiesConfig.faceDetectionModel=Face detection model [TBT] +iped.engine.config.DefaultTaskPropertiesConfig.upSampling=Up Sampling [TBT] \ No newline at end of file diff --git a/iped-app/resources/localization/iped-engine-messages_pt_BR.properties b/iped-app/resources/localization/iped-engine-messages_pt_BR.properties index 3213542ba4..c9d8e20d28 100644 --- a/iped-app/resources/localization/iped-engine-messages_pt_BR.properties +++ b/iped-app/resources/localization/iped-engine-messages_pt_BR.properties @@ -123,3 +123,245 @@ GraphAnalysis.LinksEmails=E-mails GraphAnalysis.LinksInstantMessages=Mensagens Instantâneas GraphAnalysis.LinksWireless=Redes Sem-Fio GraphAnalysis.LinksDocuments=Documentos +iped.engine.config.ImageThumbTask=Miniaturização +iped.engine.config.ImageThumbTaskConfig.name=Configurações de Miniaturização +iped.engine.config.ImageThumbTaskConfig.imgConvTimeoutPerMB=Tempo limite por MB +iped.engine.config.ImageThumbTaskConfig.imgConvTimeout=Tempo limite total +iped.engine.config.ImageThumbTaskConfig.lowResDensity=Densidade usada para baixa resoluçãoo +iped.engine.config.ImageThumbTaskConfig.highResDensity=Densidade usada para alta resolução +iped.engine.config.ImageThumbTaskConfig.maxMPixelsInMemory=Máximo de memória utilizada (MB) +iped.engine.config.ImageThumbTaskConfig.logGalleryRendering=Registrar renderizações na galeria +iped.engine.config.ImageThumbTaskConfig.imgThumbSize=Tamanho da miniatura +iped.engine.config.ImageThumbTaskConfig.externalConversionTool=Ferramenta de conversão externa +iped.engine.config.ImageThumbTaskConfig.enableExternalConv=Habilitar conversão externa +iped.engine.config.ImageThumbTaskConfig.extractThumb=Extrair miniaturas +iped.engine.config.ImageThumbTaskConfig.galleryThreads=Número de Threads +iped.engine.graph.GraphTaskConfig=Grafo +iped.engine.graph.GraphTaskConfig.comment=Configurações para criação do grafo +iped.engine.graph.GraphTaskConfig.defaultBusinessEntity=Endidade de negócio padrão +iped.engine.graph.GraphTaskConfig.defaultEntity=Entidade padrão +iped.engine.graph.GraphTaskConfig.defaultPersonEntity=Entidade pessoal padrão +iped.engine.graph.GraphTaskConfig.defaultRelationship=Relacionamento padrão +iped.engine.graph.GraphTaskConfig.detectPhonesOnOtherMimes=Detectar telefones nos arquivos mime +iped.engine.graph.GraphTaskConfig.entities=Entidades +iped.engine.task.HTMLReportTask=Geração do relatório em formato HTML +iped.engine.config.HtmlReportTaskConfig=Parâmetros para geração do relatório +iped.engine.config.HtmlReportTaskConfig.EnableThumbsGallery=Habilitar galeria de miniaturas +iped.engine.config.HtmlReportTaskConfig.ThumbSize=Tamanho das minituras +iped.engine.config.HtmlReportTaskConfig.Examiner=Examinador +iped.engine.config.HtmlReportTaskConfig.Report=Identificador do Exame +iped.engine.config.HtmlReportTaskConfig.RecordDate=Data da aquisição +iped.engine.config.HtmlReportTaskConfig.EnableImageThumbs=Habilitar miniaturas de imagens +iped.engine.config.HtmlReportTaskConfig.ThumbsPerPage=Miniaturas por página +iped.engine.config.HtmlReportTaskConfig.ItemsPerPage=Itens por página +iped.engine.config.HtmlReportTaskConfig.Title=Título +iped.engine.config.HtmlReportTaskConfig.ReportDate=Data do relatório +iped.engine.config.HtmlReportTaskConfig.Material=Identificador do Material +iped.engine.config.HtmlReportTaskConfig.EnableVideoThumbs=Habilitar miniaturas de vídeos +iped.engine.config.HtmlReportTaskConfig.RequestDoc=Documento de requisição do exame +iped.engine.config.HtmlReportTaskConfig.ExaminerID=Identificador do examinador +iped.engine.config.HtmlReportTaskConfig.Requester=Nome do requisitante +iped.engine.config.HtmlReportTaskConfig.RequestDate=Data da requisição do exame +iped.engine.config.HtmlReportTaskConfig.VideoStripeWidth=Tamanho da fatia do vídeo +iped.engine.config.HtmlReportTaskConfig.Header=Cabeçalho do Relatório +iped.engine.config.HtmlReportTaskConfig.Investigation=Nome da operação +iped.engine.config.HtmlReportTaskConfig.FramesPerStripe=Quadros por fatia +iped.engine.config.HtmlReportTaskConfig.Record=Número do registro da requisição +iped.engine.config.HtmlReportTaskConfig.EnableCategoriesList=Habilitar listagem de categorias +iped.engine.task.ParsingTask=Interpretação do conteúdo +iped.engine.task.HashTask=Cálculo de hashes +iped.engine.task.HashTask.tooltip=Tarefa de cálculo dos hashes do item encontrado. +iped.engine.config.HashTaskConfig=Opções de cálculo de hashes +iped.engine.config.HashTaskConfig.tooltip=Algoritmos usados para calcular hashes dos itens +iped.engine.config.HashTaskConfig.hashes=Algorítmos +iped.engine.config.HashTaskConfig.hashes.tooltip=Algorítmos usados para calcular os hashes +iped.engine.task.SignatureTask=Identificação de mime types +iped.engine.task.SignatureTask.tooltip=Classifica os arquivos conforme regras de identificação de mime types baseadas na especificação FreeDesktop.
(https://specifications.freedesktop.org/shared-mime-info-spec/latest/ar01s02.html). +iped.engine.config.SignatureConfig=Regras de identificação de mime types. +iped.engine.config.SignatureConfig.tooltip=Regras de identificação de mime types baseadas na especificação FreeDesktop.
(https://specifications.freedesktop.org/shared-mime-info-spec/latest/ar01s02.html). +iped.engine.task.SetCategoryTask=Categorização de items +iped.engine.config.CategoryConfig=Categorização baseada em mime types +iped.engine.config.CategoryConfig.tooltip=Especifique quais items serão classificados em cada categoria baseado em seus mime types. +iped.engine.task.HashDBLookupTask=Busca na base de hashes conhecidos +iped.engine.task.HashDBLookupTask.tooltip=Adiciona propriedades salvas aos itens cujos hashes foram encontrados na base de hashes conhecidos. +iped.engine.task.DuplicateTask=Identificação de duplicatas +iped.engine.task.DuplicateTask.tooltip=Correlaciona items com mesmo hashes encontrados no caso +iped.engine.task.transcript.AudioTranscriptTask=Transcrição de áudios +iped.engine.config.AudioTranscriptConfig=Parâmetros para transcrição de áudios +iped.engine.config.AudioTranscriptConfig.implementationClass=Classe +iped.engine.config.AudioTranscriptConfig.implementationClass.tooltip=Nome completo da classe java que irá executar a transcrição. +iped.engine.config.AudioTranscriptConfig.language=Lígua +iped.engine.config.AudioTranscriptConfig.convertCommand=Comando para conversão em WAV +iped.engine.config.AudioTranscriptConfig.mimesToProcess=Mime types a serem processados +iped.engine.config.AudioTranscriptConfig.timeout=Tempo limite da transcrição +iped.engine.config.AudioTranscriptConfig.minWordScore=Mínima pontuação de palavras +iped.engine.config.AudioTranscriptConfig.serviceRegion=Região +iped.engine.config.AudioTranscriptConfig.maxConcurrentRequests=Máximo número de requisições concorrentes +iped.engine.config.AudioTranscriptConfig.requestIntervalMillis=Intervalo entre as requisições (ms) +iped.engine.config.AudioTranscriptConfig.googleModel=Modelo da Google +iped.engine.task.video.VideoThumbTask=Criação de miniaturas de vídeos +iped.engine.task.video.VideoThumbTask.tooltip=Criação de miniaturas de vídeos +iped.engine.config.VideoThumbsConfig=Parâmetros para criação de miniaturas de vídeos +iped.engine.config.VideoThumbsConfig.tooltip=Parâmetros para criação de miniaturas de vídeos +iped.engine.config.VideoThumbsConfig.Layout=Layout +iped.engine.config.VideoThumbsConfig.Timeouts=Tempo limite +iped.engine.config.VideoThumbsConfig.Verbose=Verbose +iped.engine.config.VideoThumbsConfig.GalleryThumbs=Miniaturas para a galeria +iped.engine.config.VideoThumbsConfig.enableVideoThumbsSubitems=Habilitar subitens +iped.engine.config.VideoThumbsConfig.enableVideoThumbsOriginalDimension=Habilitar dimensão original +iped.engine.config.VideoThumbsConfig.maxDimensionSize=Dimensão máxima +iped.engine.task.QRCodeTask=Extração de informações de QRCodes +iped.engine.task.regex.RegexTask=Extrações de correspondências com expressões regulares +iped.engine.config.RegexTaskConfig=Expressões regulares +iped.engine.config.RegexTaskConfig.tooltip=Expressões regulares +iped.engine.config.RegexTaskConfig.formatMatches=Formatar correspondências +iped.engine.config.RegexTaskConfig.formatMatches.tooltip=Formatar correspondências +iped.engine.task.LanguageDetectTask=Detecção de linguagem +iped.engine.task.LanguageDetectTask.tooltip=Detecção de linguagem do conteúdo textual +iped.engine.task.NamedEntityTask=Detecção de entidades +iped.engine.task.NamedEntityTask.tooltip=Detecção de entidades no conteúdo textual +iped.engine.config.NamedEntityTaskConfig=Parâmetros para detecção de entidades +iped.engine.config.NamedEntityTaskConfig.NERImpl=Classe +iped.engine.config.NamedEntityTaskConfig.langModel_0=Modelo linguístico +iped.engine.config.NamedEntityTaskConfig.minLangScore=Mínima pontuação da linguagem +iped.engine.config.NamedEntityTaskConfig.mimeTypesToIgnore=Ignorar os mime types +iped.engine.config.NamedEntityTaskConfig.categoriesToIgnore=Ignorar as categorias +iped.engine.task.ExportFileTask=Exportar arquivos +iped.engine.config.ExportByCategoriesConfig=Categorias a exportar +iped.engine.config.ExportByKeywordsConfig=Exportação baseada em palavras-chave +iped.engine.task.EmbeddedDiskProcessTask=Extração de disco embutido +iped.engine.task.MakePreviewTask=Criação de pré-visualizações +iped.engine.config.MakePreviewConfig=Seleção de mime types +iped.engine.config.MakePreviewConfig.supportedMimeTypes=Mime types suportados +iped.engine.config.MakePreviewConfig.supportedMimeTypesWithLinks=Mime types suportados com links +iped.engine.task.DocThumbTask=Criação de miniaturas de documentos +iped.engine.config.DocThumbTaskConfig=Parâmetros +iped.engine.config.DocThumbTaskConfig.pdfThumbs=Miniaturas de PDFs +iped.engine.config.DocThumbTaskConfig.libreOfficeThumbs=Miniaturas de documentos Libre Office +iped.engine.config.DocThumbTaskConfig.pdfTimeout=Tempo limite para criação de miniaturas PDF +iped.engine.config.DocThumbTaskConfig.libreOfficeTimeout=Tempo limite para criação de miniaturas Libre Office +iped.engine.config.DocThumbTaskConfig.timeoutIncPerMB=Incremento do tempo limite por tamanho (MB) +iped.engine.config.DocThumbTaskConfig.thumbSize=Tamanho da miniatura +iped.engine.config.DocThumbTaskConfig.maxPdfExternalMemory=Memória externa máxima para criação de PDFs +iped.engine.task.die.DIETask=Detecção de imagens explícitas +iped.engine.task.die.DIETask.tooltip=Atribui pontuações de nudez ao conteúdo das imagens +iped.engine.task.similarity.ImageSimilarityTask=Extração de vetores de características para imagens +iped.engine.task.similarity.ImageSimilarityTask.tooltip=Extrai vetores de características das imagens para serem usadas em busca por imagens semelhantes +iped.engine.task.PhotoDNATask=Cálculo do Photo DNA +iped.engine.config.PhotoDNAConfig=Parâmetros para o cálculo do Photo DNA +iped.engine.config.PhotoDNAConfig.computeFromThumbnail=Calcular a partir do thumbnail +iped.engine.config.PhotoDNAConfig.minFileSize=Tamanho mínimo do arquivo +iped.engine.config.PhotoDNAConfig.skipHashDBFiles=Ignorar arquivos encontrados nas bases de hash. +iped.engine.task.PhotoDNALookup=Busca em bases de Photo DNA +iped.engine.task.PhotoDNALookup.tooltip=Extrai propriedades de base de dados baseado no valor do Photo DNA +iped.engine.config.PhotoDNALookupConfig=Parâmetros de busca na base de dados +iped.engine.config.PhotoDNALookupConfig.statusHashDBFilter=Filtro por status do hash +iped.engine.config.PhotoDNALookupConfig.maxSimilarityDistance=Máxima distância de similaridade +iped.engine.config.PhotoDNALookupConfig.searchRotatedAndFlipped=Buscar por imagens espelhadas ou rotacionadas +iped.engine.task.carver.LedCarveTask=Carve itens salvos na base LED +iped.engine.task.carver.LedCarveTask.tooltip=Carve itens cujo hash dos primeiros 64K bytes estão salvos na base LED +iped.engine.task.carver.CarverTask=Carve itens +iped.engine.task.carver.CarverTask.tooltip=Carve itens a partir de informações de cabeçalho e/ou carvers customizados +iped.engine.task.carver.KnownMetCarveTask=Carve arquivos knownmet do Emule +iped.engine.task.carver.KnownMetCarveTask.tooltip=Carve Emule knownmet files +iped.engine.task.FragmentLargeBinaryTask=Fragmentar aquivos binários grandes +iped.engine.config.SplitLargeBinaryConfig=Parâmetros da fragmentação +iped.engine.config.SplitLargeBinaryConfig.minItemSizeToFragment=Tamanho mínio do fragmento +iped.engine.config.SplitLargeBinaryConfig.itemFragmentSize=Tamanho do fragmento +iped.engine.config.SplitLargeBinaryConfig.fragmentOverlapSize=Tamanho da sobreposição dos fragmentos +iped.engine.task.EntropyTask=Cálculo da entropia +iped.engine.task.EntropyTask.tooltip=Cálculo da entropia do item +iped.engine.task.MinIOTask=MinIO +iped.engine.config.MinIOConfig=Configurações do MinIO +iped.engine.config.MinIOConfig.host=Endereço IP +iped.engine.config.MinIOConfig.port=Porta TCP +iped.engine.config.MinIOConfig.zipFilesMaxSize=Tamanho máximo do arquivo ZIP +iped.engine.config.MinIOConfig.updateRefsToMinIO=Atualizar referências no MinIO +iped.engine.config.MinIOConfig.timeOut=Tempo limite +iped.engine.config.MinIOConfig.retries=Número de novas tentativas +iped.engine.task.index.ElasticSearchIndexTask=Integração com o Elastic Search +iped.engine.config.ElasticSearchTaskConfig=Parâmetros do Elastic Seach +iped.engine.config.ElasticSearchTaskConfig.host=Endereço IP do servidor +iped.engine.config.ElasticSearchTaskConfig.port=Porta do servidor +iped.engine.config.ElasticSearchTaskConfig.protocol=Protocolo do servidor +iped.engine.config.ElasticSearchTaskConfig.index.number_of_shards=Número de fragmentos +iped.engine.config.ElasticSearchTaskConfig.index.number_of_replicas=Número de réplicas +iped.engine.config.ElasticSearchTaskConfig.min_bulk_size=Tamanho mínimo do volume +iped.engine.config.ElasticSearchTaskConfig.min_bulk_items=Numéro mínimo de itens do volume +iped.engine.config.ElasticSearchTaskConfig.max_async_requests=Máximo de requisições assíncronas +iped.engine.config.ElasticSearchTaskConfig.timeout_millis=Tempo limite +iped.engine.config.ElasticSearchTaskConfig.connect_timeout_millis=Tempo limite para conexão +iped.engine.config.ElasticSearchTaskConfig.index.mapping.total_fields.limit=Número máximo de campos +iped.engine.config.ElasticSearchTaskConfig.useCustomAnalyser=Usar analisador customizado +iped.engine.config.ElasticSearchTaskConfig.validateSSL=Validar conexão SSL +iped.engine.config.ElasticSearchTaskConfig.useTermVector=Usar vetores de termos +iped.engine.task.index.IndexTask=Indexação +iped.engine.task.index.IndexTask.tooltip=Indexação com o Lucene do conteúdo e metadados extraídos de cada item. +iped.engine.config.IndexTaskConfig=Parâmetros da indexação +iped.engine.config.IndexTaskConfig.indexUnallocated=Indexar arquivos não alocados +iped.engine.config.IndexTaskConfig.convertCharsToLowerCase=Converter caracteres para minísculo +iped.engine.config.IndexTaskConfig.convertCharsToAscii=Converter caracteres para ASCII +iped.engine.config.IndexTaskConfig.extraCharsToIndex=Caracteres adicionais para indexar +iped.engine.config.IndexTaskConfig.filterNonLatinChars=Filtrar caracteres não latinos +iped.engine.config.IndexTaskConfig.textSplitSize=Tamanho dos fragmentos de texto +iped.engine.config.IndexTaskConfig.useNIOFSDirectory=Usar sistema de arquivos NIO +iped.engine.config.IndexTaskConfig.forceMerge=Forçar mescla +iped.engine.config.IndexTaskConfig.storeTermVectors=Armazenar vetores de termos +iped.engine.config.IndexTaskConfig.maxTokenLength=Tamanho máximo do token +iped.engine.config.IndexTaskConfig.commitIntervalSeconds=Intervalo de commit em disco +iped.engine.graph.GraphTask=Geração do grafo +iped.engine.task.ExportCSVTask=Exportar as propriedades para arquivo CSV +iped.engine.task.ExportCSVTask.tooltip=Exportar as propriedades para arquivo CSV +iped.engine.config.CategoryToExpandConfig=Categorias a expandir +iped.engine.config.CategoryToExpandConfig.tooltip=Selecionar categorias que terão subitens expandidos e incluídos na fila de processamento +iped.engine.config.ParsingTaskConfig=Parâmetros de interpretação +iped.engine.config.ParsingTaskConfig.enableExternalParsing=Habilitar interpretadores externos +iped.engine.config.ParsingTaskConfig.numExternalParsers=Número de processos para interpretadores externos +iped.engine.config.ParsingTaskConfig.externalParsingMaxMem=Máximo de memória por interpretadores externos +iped.engine.config.ParsingTaskConfig.parseUnknownFiles=Interpretar arquivos desconhecidos +iped.engine.config.ParsingTaskConfig.parseCorruptedFiles=Interpretar arquivos corrompidos +iped.engine.config.ParsingTaskConfig.timeOut=Tempo limite de interpretação de um item +iped.engine.config.ParsingTaskConfig.timeOutPerMB=Incremento to tempo limite de interpretação/MB +iped.engine.config.ParsingTaskConfig.minRawStringSize=Tamanho mínimo de strings brutas +iped.engine.config.ParsingTaskConfig.phoneParsersToUse=Interpretador de número de telefone +iped.engine.config.ParsingTaskConfig.sortPDFChars=Ordenar caracteres em PDFs +iped.engine.config.ParsingTaskConfig.processImagesInPDFs=Processar imagems em PDFs +iped.engine.config.ParsingTaskConfig.storeTextCacheOnDisk=Armazenar cache de texto em disco +iped.engine.config.OCRConfig=Parâmetros do OCR +iped.engine.config.OCRConfig.enableOCR=Habilitar OCF +iped.engine.config.OCRConfig.OCRLanguage=Linguagem do OCR +iped.engine.config.OCRConfig.pageSegMode=Modo de segmentação de página +iped.engine.config.OCRConfig.minFileSize2OCR=Tamanho mínimo da imagem para processar. +iped.engine.config.OCRConfig.pdfToImgResolution=Resolution da conversão do PDF para imagem +iped.engine.config.OCRConfig.maxPDFTextSize2OCR=Tamanho máximo do arquivo PDF a processar +iped.engine.config.OCRConfig.pdfToImgLib=Biblioteca de conversão de PDF para imagem +iped.engine.config.OCRConfig.externalPdfToImgConv=Conversão externa do PDF para imagem +iped.engine.config.OCRConfig.externalConvMaxMem=Máximo de memória para a conversão externa +iped.engine.config.OCRConfig.processNonStandard=Processar fora do padrão +iped.engine.config.OCRConfig.maxConvImageSize=Tamanho máximo da imagem +iped.engine.config.ParsersConfig=Configuração dos interpretadores +iped.engine.config.ExternalParsersConfig=Interpretadores externos +iped.engine.config.FileSystemConfig=Opções das evidências +iped.engine.config.FileSystemConfig.robustImageReading=Leitura de imagem robusta +iped.engine.config.FileSystemConfig.numImageReaders=Numero de leitores em paralelo +iped.engine.config.FileSystemConfig.addUnallocated=Processar espaço não alocado +iped.engine.config.FileSystemConfig.addFileSlacks=Processar espaço não utilizado pelo arquivo +iped.engine.config.FileSystemConfig.minOrphanSizeToIgnore=Minimo de arquivos órfãos para processar +iped.engine.config.FileSystemConfig.unallocatedFragSize=Tamanho dos fragmentos do espaço não alocado +iped.engine.config.FileSystemConfig.ignoreHardLinks=Ignorar links físicos +iped.engine.config.FileSystemConfig.skipFolderRegex=Não processar pastas com o regex +iped.engine.task.SkipCommitedTask=Ignorar tarefas com commit +iped.engine.task.SkipCommitedTask.tooltip=Ignorar arquivos com commit finalizado +iped.engine.task.TempFileTask=Geração do arquivo temporário +iped.engine.task.TempFileTask.tooltip=Cria arquivo temporário para evitar comandos repetitivos de descompactação, leitura da rede ou de discos lentos. +iped.engine.task.SetTypeTask=Classificação por tipo MIME +iped.engine.task.SetTypeTask.tooltip=Classifica o item com base em seu mime-type +iped.engine.task.IgnoreHardLinkTask=Ignora referências físicas +iped.engine.task.IgnoreHardLinkTask.tooltip=Ignora processamento de conteúdo de referências físicas +iped.engine.task.RefineCategoryTask=Refinar categorias +iped.engine.task.RefineCategoryTask.tooltip=Refina a categorização de itens encontrados +iped.engine.task.PythonTask.FaceRecognitionTask.py=Reconhecimento facial +iped.engine.config.DefaultTaskPropertiesConfig=Reconhecimento facial +iped.engine.config.DefaultTaskPropertiesConfig.maxResolution=Resolução máxima +iped.engine.config.DefaultTaskPropertiesConfig.faceDetectionModel=Modelo utilizado +iped.engine.config.DefaultTaskPropertiesConfig.upSampling=Up Sampling \ No newline at end of file diff --git a/iped-app/resources/root/iped-gui.exe b/iped-app/resources/root/iped-gui.exe new file mode 100644 index 0000000000..62558021d8 Binary files /dev/null and b/iped-app/resources/root/iped-gui.exe differ diff --git a/iped-app/resources/scripts/tasks/SearchHardwareWallets.py b/iped-app/resources/scripts/tasks/SearchHardwareWallets.py index 14c635fc27..e3327b8294 100644 --- a/iped-app/resources/scripts/tasks/SearchHardwareWallets.py +++ b/iped-app/resources/scripts/tasks/SearchHardwareWallets.py @@ -7,8 +7,10 @@ import os import re -from iped.parsers.registry import RegRipperParser -reportSuffix = RegRipperParser.FULL_REPORT_SUFFIX +# this constant must coincide with the value of +# iped.parsers.registry.RegRipperParser.FULL_REPORT_SUFFIX script +reportSuffix = '_Full_Report' + configFile = 'hardwarewallets.json' hwFound = 'Hardware-Wallet-Found' diff --git a/iped-app/resources/scripts/tasks/jstemplates/CreateQueryBookmark.js b/iped-app/resources/scripts/tasks/jstemplates/CreateQueryBookmark.js new file mode 100644 index 0000000000..158ccf6a1f --- /dev/null +++ b/iped-app/resources/scripts/tasks/jstemplates/CreateQueryBookmark.js @@ -0,0 +1,91 @@ +/* + * Javascript processing task example. It must be installed in TaskInstaller.xml to be executed. + * Must be implemented at least methods getName() and process(item). + * Script tasks can access properties, extracted text and raw content of items. Based on that, + * it can ignore items, set extra attributes or create bookmarks. + */ + + /* Returns the task name. */ +function getName(){ + return "CreateQueryBookmark"; +} + +/* + * Returns + an optional list of configurable objects that can load/save parameters from/to config files. + */ +function getConfigurables(){ + return null; +} + +/* Do some task initialization, like reading options and cofiguration params. + * This method is executed before starting the processing of items. + * It is executed by each processing thread. + * @Params + * configuration: configuration manager by which configurables could be retrieved after populated. + */ +function init(configuration){ + //init code here +} + +/* Finish task, maybe cleaning resources. It is executed after processing all items in case. + * It is executed by each processing thread. + * Objects "ipedCase" and "searcher" are shared, so case can be queried for items and bookmarks can be created, for example. + * TODO: document methods of those objects. + */ +function finish(){ +} + +/* Finish task, maybe cleaning resources. It is executed after processing all items in case. + * It is executed by each processing thread. + * Objects "ipedCase" and "searcher" are shared, so case can be queried for items and bookmarks can be created, for example. + * TODO: document methods of those objects. + */ +function executeAfterAll(){ + //Bookmark creation example + var query = "type:pdf"; + + //set query into searcher + searcher.setQuery(query); + + //search in case and return item ids + var ids = searcher.search().getIds(); + + //create new bookmark and get its id + var bookmarkId = ipedCase.getBookmarks().newBookmark("PDF files"); + + //set bookmark comment + ipedCase.getBookmarks().setBookmarkComment(bookmarkId, "Documents of PDF file format"); + + //add item ids to created bookmark + ipedCase.getBookmarks().addBookmark(ids, bookmarkId); + + //save changes synchronously + ipedCase.getBookmarks().saveState(true); +} + +/* + * Process object "item" of EvidenceFile class. This function is executed on all case items. + * It can access any method of EvidenceFile class: + * + * Some Getters: + * String: getName(), getExt(), getType(), getPath(), getHash(), getMediaType().toString(), getCategories() (categories separated by | ) + * Date: getModDate(), getCreationDate(), getAccessDate() (podem ser nulos) + * Boolean: isDeleted(), isDir(), isRoot(), isCarved(), isSubItem(), isTimedOut(), hasChildren() + * Long: getLength() + * Metadata getMetadata() + * Object: getExtraAttribute(String key) (returns an extra attribute) + * String: getParsedTextCache() (returns item extracted text, if this task is placed after ParsingTask) + * File: getTempFile() (returns a temp file with item content) + * BufferedInputStream: getBufferedInputStream() (returns an InputStream with item content) + * + * Some Setters: + * setToIgnore(boolean) (ignores the item and excludes it from processing and case) + * setAddToCase(boolean) (inserts or not item in case, after being processed: default true) + * addCategory(String), removeCategory(String), setMediaTypeStr(String) + * setExtraAttribute(key, value), setParsedTextCache(String) + * + */ +function process(item){ + //This template does not need to process items individually +} diff --git a/iped-app/resources/scripts/tasks/jstemplates/ExampleScriptTask.js b/iped-app/resources/scripts/tasks/jstemplates/ExampleScriptTask.js new file mode 100644 index 0000000000..e4b28f9bcd --- /dev/null +++ b/iped-app/resources/scripts/tasks/jstemplates/ExampleScriptTask.js @@ -0,0 +1,95 @@ +/* + * Javascript processing task example. It must be installed in TaskInstaller.xml to be executed. + * Must be implemented at least methods getName() and process(item). + * Script tasks can access properties, extracted text and raw content of items. Based on that, + * it can ignore items, set extra attributes or create bookmarks. + */ + + /* Returns the task name. */ +function getName(){ + return "ExampleScriptTask"; +} + +/* + * Returns + an optional list of configurable objects that can load/save parameters from/to config files. + */ +function getConfigurables(){ + return null; +} + +/* Do some task initialization, like reading options and cofiguration params. + * This method is executed before starting the processing of items. + * It is executed by each processing thread. + * @Params + * configuration: configuration manager by which configurables could be retrieved after populated. + */ +function init(configuration){ + //init code here +} + +/* Finish task, maybe cleaning resources. It is executed after processing all items in case. + * It is executed by each processing thread. + * Objects "ipedCase" and "searcher" are shared, so case can be queried for items and bookmarks can be created, for example. + * TODO: document methods of those objects. + */ +function finish(){ + //Bookmark creation example + /* + var query = "type:pdf"; + + //set query into searcher + searcher.setQuery(query); + + //search in case and return item ids + var ids = searcher.search().getIds(); + + //create new bookmark and get its id + var bookmarkId = ipedCase.getBookmarks().newBookmark("PDF files"); + + //set bookmark comment + ipedCase.getBookmarks().setBookmarkComment(bookmarkId, "Documents of PDF file format"); + + //add item ids to created bookmark + ipedCase.getBookmarks().addBookmark(ids, bookmarkId); + + //save changes synchronously + ipedCase.getBookmarks().saveState(true); + */ +} + +/* + * Process object "item" of EvidenceFile class. This function is executed on all case items. + * It can access any method of EvidenceFile class: + * + * Some Getters: + * String: getName(), getExt(), getType(), getPath(), getHash(), getMediaType().toString(), getCategories() (categories separated by | ) + * Date: getModDate(), getCreationDate(), getAccessDate() (podem ser nulos) + * Boolean: isDeleted(), isDir(), isRoot(), isCarved(), isSubItem(), isTimedOut(), hasChildren() + * Long: getLength() + * Metadata getMetadata() + * Object: getExtraAttribute(String key) (returns an extra attribute) + * String: getParsedTextCache() (returns item extracted text, if this task is placed after ParsingTask) + * File: getTempFile() (returns a temp file with item content) + * BufferedInputStream: getBufferedInputStream() (returns an InputStream with item content) + * + * Some Setters: + * setToIgnore(boolean) (ignores the item and excludes it from processing and case) + * setAddToCase(boolean) (inserts or not item in case, after being processed: default true) + * addCategory(String), removeCategory(String), setMediaTypeStr(String) + * setExtraAttribute(key, value), setParsedTextCache(String) + * + */ +function process(item){ + //Ignore item example + /* + if(item.getExt().equals("dll")) + item.setToIgnore(true); + */ + + //Create attribute example + /* WARN: searching for text in all items in case will be very slow! + if(item.getParsedTextCache().toLowerCase().indexOf("maria da silva") != -1) + item.setExtraAttribute("containsMaria", "true"); + */ +} diff --git a/iped-app/resources/scripts/tasks/jstemplates/ExtractMetadata.js b/iped-app/resources/scripts/tasks/jstemplates/ExtractMetadata.js new file mode 100644 index 0000000000..1e0d9cf4dc --- /dev/null +++ b/iped-app/resources/scripts/tasks/jstemplates/ExtractMetadata.js @@ -0,0 +1,66 @@ +/* + * Javascript processing task example. It must be installed in TaskInstaller.xml to be executed. + * Must be implemented at least methods getName() and process(item). + * Script tasks can access properties, extracted text and raw content of items. Based on that, + * it can ignore items, set extra attributes or create bookmarks. + */ + + /* Returns the task name. */ +function getName(){ + return "ExtractMetadata"; +} + +/* + * Returns + an optional list of configurable objects that can load/save parameters from/to config files. + */ +function getConfigurables(){ + return null; +} + +/* Do some task initialization, like reading options and cofiguration params. + * This method is executed before starting the processing of items. + * It is executed by each processing thread. + * @Params + * configuration: configuration manager by which configurables could be retrieved after populated. + */ +function init(configuration){ +} + +/* Finish task, maybe cleaning resources. It is executed after processing all items in case. + * It is executed by each processing thread. + * Objects "ipedCase" and "searcher" are shared, so case can be queried for items and bookmarks can be created, for example. + * TODO: document methods of those objects. + */ +function finish(){ +} + +/* + * Process object "item" of EvidenceFile class. This function is executed on all case items. + * It can access any method of EvidenceFile class: + * + * Some Getters: + * String: getName(), getExt(), getType(), getPath(), getHash(), getMediaType().toString(), getCategories() (categories separated by | ) + * Date: getModDate(), getCreationDate(), getAccessDate() (podem ser nulos) + * Boolean: isDeleted(), isDir(), isRoot(), isCarved(), isSubItem(), isTimedOut(), hasChildren() + * Long: getLength() + * Metadata getMetadata() + * Object: getExtraAttribute(String key) (returns an extra attribute) + * String: getParsedTextCache() (returns item extracted text, if this task is placed after ParsingTask) + * File: getTempFile() (returns a temp file with item content) + * BufferedInputStream: getBufferedInputStream() (returns an InputStream with item content) + * + * Some Setters: + * setToIgnore(boolean) (ignores the item and excludes it from processing and case) + * setAddToCase(boolean) (inserts or not item in case, after being processed: default true) + * addCategory(String), removeCategory(String), setMediaTypeStr(String) + * setExtraAttribute(key, value), setParsedTextCache(String) + * + */ +function process(item){ + //Create attribute example + /* WARN: searching for text in all items in case will be very slow! */ + if(item.getParsedTextCache().toLowerCase().indexOf("maria da silva") != -1) + item.setExtraAttribute("containsMaria", "true"); + +} diff --git a/iped-app/resources/scripts/tasks/jstemplates/FilterItems.js b/iped-app/resources/scripts/tasks/jstemplates/FilterItems.js new file mode 100644 index 0000000000..9c1eac9cbb --- /dev/null +++ b/iped-app/resources/scripts/tasks/jstemplates/FilterItems.js @@ -0,0 +1,66 @@ +/* + * Javascript processing task example. It must be installed in TaskInstaller.xml to be executed. + * Must be implemented at least methods getName() and process(item). + * Script tasks can access properties, extracted text and raw content of items. Based on that, + * it can ignore items, set extra attributes or create bookmarks. + */ + + /* Returns the task name. */ +function getName(){ + return "FilterItems"; +} + +/* + * Returns + an optional list of configurable objects that can load/save parameters from/to config files. + */ +function getConfigurables(){ + return null; +} + +/* Do some task initialization, like reading options and cofiguration params. + * This method is executed before starting the processing of items. + * It is executed by each processing thread. + * @Params + * configuration: configuration manager by which configurables could be retrieved after populated. + */ +function init(configuration){ + //init code here +} + +/* Finish task, maybe cleaning resources. It is executed after processing all items in case. + * It is executed by each processing thread. + * Objects "ipedCase" and "searcher" are shared, so case can be queried for items and bookmarks can be created, for example. + * TODO: document methods of those objects. + */ +function finish(){ +} + +/* + * Process object "item" of EvidenceFile class. This function is executed on all case items. + * It can access any method of EvidenceFile class: + * + * Some Getters: + * String: getName(), getExt(), getType(), getPath(), getHash(), getMediaType().toString(), getCategories() (categories separated by | ) + * Date: getModDate(), getCreationDate(), getAccessDate() (podem ser nulos) + * Boolean: isDeleted(), isDir(), isRoot(), isCarved(), isSubItem(), isTimedOut(), hasChildren() + * Long: getLength() + * Metadata getMetadata() + * Object: getExtraAttribute(String key) (returns an extra attribute) + * String: getParsedTextCache() (returns item extracted text, if this task is placed after ParsingTask) + * File: getTempFile() (returns a temp file with item content) + * BufferedInputStream: getBufferedInputStream() (returns an InputStream with item content) + * + * Some Setters: + * setToIgnore(boolean) (ignores the item and excludes it from processing and case) + * setAddToCase(boolean) (inserts or not item in case, after being processed: default true) + * addCategory(String), removeCategory(String), setMediaTypeStr(String) + * setExtraAttribute(key, value), setParsedTextCache(String) + * + */ +function process(item){ + //use set to Ignore to filter this item from following processing tasks + if(item.getExt().equals("dll")){ + item.setToIgnore(true); + } +} diff --git a/iped-app/resources/scripts/tasks/pythontemplates/PythonScriptTask.py b/iped-app/resources/scripts/tasks/pythontemplates/PythonScriptTask.py new file mode 100644 index 0000000000..3947805fcd --- /dev/null +++ b/iped-app/resources/scripts/tasks/pythontemplates/PythonScriptTask.py @@ -0,0 +1,84 @@ +# Python task script example. It must be installed in TaskInstaller.xml to be executed. +# The script could access any item properties, extracted text, thumbs and raw bytes. +# The script can set extra item properties/columns in process() method, ignore items or create bookmarks in finish(). +# On Linux, you need to install jep (pip install jep) and include jep.so in LD_LIBRARY_PATH. +# see https://github.com/sepinf-inc/IPED/wiki/User-Manual#python-modules + + +# The main class name must be equal to the script file name without .py extension +# One instance of this class is created by each processing thread and each thread calls the implemented methods of its own object. +class PythonScriptTask: + + # Returns if this task is enabled or not. This could access options read by init() method. + def isEnabled(self): + return True + + # Returns an optional list of configurable objects that can load/save parameters from/to config files. + def getConfigurables(self): + return [] + + # Do some task initialization, like reading options, custom config files or model. + # It is executed when application starts by each processing thread on its class instance. + # @Params + # configuration: configuration manager by which configurables can be retrieved after populated. + def init(self, configuration): + #print("init") + return + + + # Finish method run after processing all items in case, e.g. to clean resources. + # It is executed by each processing thread on its class instance. + # Objects "ipedCase" and "searcher" are provided, so case can be queried for items and bookmarks can be created, for example. + # TODO: document methods of those objects. + def finish(self): + + query = "type:doc" + + #set query into searcher + searcher.setQuery(query) + + #search in case and return item ids + ids = searcher.search().getIds() + + #create new bookmark and get its id + bookmarkId = ipedCase.getBookmarks().newBookmark("DOC files") + + #set bookmark comment + ipedCase.getBookmarks().setBookmarkComment(bookmarkId, "Documents of DOC file format") + + #add item ids to created bookmark + ipedCase.getBookmarks().addBookmark(ids, bookmarkId) + + #save changes synchronously + ipedCase.getBookmarks().saveState(True) + + + # Process an Item object. This method is executed on all case items. + # It can access any method of Item class and store results as a new extra attribute. + # + # Some Getters: + # String: getName(), getExt(), getType(), getPath(), getHash(), getMediaType().toString(), getCategories() (categories separated by | ) + # Date: getModDate(), getCreationDate(), getAccessDate() (podem ser nulos) + # Boolean: isDeleted(), isDir(), isRoot(), isCarved(), isSubItem(), isTimedOut(), hasChildren() + # Long: getLength() + # Metadata getMetadata() + # Object: getExtraAttribute(String key) (returns an extra attribute) + # String: getParsedTextCache() (returns item extracted text, if this task is placed after ParsingTask) + # File: getTempFile() (returns a temp file with item content) + # BufferedInputStream: getBufferedInputStream() (returns an InputStream with item content) + # + # Some Setters: + # setToIgnore(boolean) (ignores the item and excludes it from processing and case) + # setAddToCase(boolean) (inserts or not item in case, after being processed: default true) + # addCategory(String), removeCategory(String), setMediaTypeStr(String) + # setExtraAttribute(key, value), setParsedTextCache(String) + # + def process(self, item): + + # Ignore item example + if item.getExt() is not None and ".dll" in item.getExt().lower(): + item.setToIgnore(True) + + # Create extra attribute/column example + if item.getParsedTextCache() is not None and ".com" in item.getParsedTextCache().lower(): + item.setExtraAttribute("containsDotCom", True) \ No newline at end of file diff --git a/iped-app/src/main/java/iped/app/bootstrap/Bootstrap.java b/iped-app/src/main/java/iped/app/bootstrap/Bootstrap.java index 8644f3ae0d..4a2468d7ac 100644 --- a/iped-app/src/main/java/iped/app/bootstrap/Bootstrap.java +++ b/iped-app/src/main/java/iped/app/bootstrap/Bootstrap.java @@ -1,5 +1,6 @@ package iped.app.bootstrap; +import java.awt.*; import java.io.BufferedReader; import java.io.File; import java.io.IOException; @@ -17,6 +18,9 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import iped.app.home.MainFrame; +import iped.app.ui.AppMain; +import org.apache.commons.lang.ArrayUtils; import org.apache.tika.utils.SystemUtils; import ag.ion.bion.officelayer.application.IOfficeApplication; @@ -35,7 +39,7 @@ /** * Bootstrap class to start the main application process with a custom classpath * with plugin jars. - * + * * @author Luís Nassif * */ @@ -73,6 +77,15 @@ protected float getRAMToHeapFactor() { protected void run(String args[]) { + + boolean isIpedSearchApp = getMainClassName().equalsIgnoreCase( AppMain.class.getCanonicalName() ) ; + //Check if no args was passed and if there is any display available to run graphical interface + if((!isIpedSearchApp) && ArrayUtils.isEmpty(args) && ( ! ArrayUtils.isEmpty(GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) ) ){ + MainFrame.main(args); + return; + } + + List heapArgs = new ArrayList<>(); List finalArgs = new ArrayList<>(); boolean XmxDefined = false; @@ -131,13 +144,13 @@ protected void run(String args[]) { iped.setLogConfiguration(logConfig); Configuration.getInstance().loadConfigurables(iped.getConfigPath(), false); - + configLoaded(); - + String classpath = getDefaultClassPath(iped); - + PluginConfig pluginConfig = ConfigurationManager.get().findObject(PluginConfig.class); - + if (pluginConfig.getTskJarFile() != null) { classpath += separator + pluginConfig.getTskJarFile().getAbsolutePath(); } @@ -172,7 +185,7 @@ protected void run(String args[]) { cmd.add("-Djava.net.useSystemProxies=true"); // fix for #1446 cmd.add(getMainClassName()); cmd.addAll(finalArgs); - + ProcessBuilder pb = new ProcessBuilder(); // pb.directory(directory) pb.command(cmd); @@ -206,7 +219,7 @@ public void run() { System.exit(exit); } - + private static void cleanTempFolder() { if (subProcessTempFolder != null && subProcessTempFolder.isDirectory()) { for (File file : subProcessTempFolder.listFiles()) { @@ -227,7 +240,7 @@ private static void cleanTempFolder() { protected void configLoaded() { new SplashScreenManager().start(); } - + private static List getCustomJVMArgs(){ return Arrays.asList("-XX:+IgnoreUnrecognizedVMOptions", "-XX:+HeapDumpOnOutOfMemoryError", diff --git a/iped-app/src/main/java/iped/app/home/DefaultPanel.java b/iped-app/src/main/java/iped/app/home/DefaultPanel.java new file mode 100644 index 0000000000..8ecc0c059c --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/DefaultPanel.java @@ -0,0 +1,34 @@ +package iped.app.home;/* + * @created 07/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import java.awt.Color; +import java.awt.Insets; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; + +import iped.app.home.style.StyleManager; + +public abstract class DefaultPanel extends JPanel { + protected MainFrame mainFrame; + private static final Insets defaultInsets = StyleManager.getDefaultPanelInsets(); + private Color currentBackGroundColor = Color.white; + + public DefaultPanel(MainFrame mainFrame) { + super(); + this.setBorder(BorderFactory.createEmptyBorder(defaultInsets.top, defaultInsets.left, defaultInsets.bottom, defaultInsets.right)); + this.mainFrame = mainFrame; + this.setBackground(currentBackGroundColor); + this.createAndShowGUI(); + } + + public Color getCurrentBackGroundColor() { + return currentBackGroundColor; + } + + protected abstract void createAndShowGUI(); + +} diff --git a/iped-app/src/main/java/iped/app/home/HomePanel.java b/iped-app/src/main/java/iped/app/home/HomePanel.java new file mode 100644 index 0000000000..d54deed7df --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/HomePanel.java @@ -0,0 +1,182 @@ +package iped.app.home; + +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Image; +import java.awt.Insets; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.util.Objects; + +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.SwingConstants; + +/* + * @created 05/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import iped.app.home.style.StyleManager; +import iped.app.ui.Messages; + +/** + * This is the Home Panel - the App start page here we got the app logo and + * first options + */ +public class HomePanel extends DefaultPanel { + + public HomePanel(MainFrame mainFrame) { + super(mainFrame); + } + + /** + * Prepare everything to be displayed + */ + protected void createAndShowGUI() { + this.setLayout(new GridBagLayout()); + this.setBackground(Color.white); + createAndSetupAppLogo(); + createAndSetupOptionsButtons(); + } + + /** + * Create and setup IPED Application Logo panel + */ + private void createAndSetupAppLogo() { + String IPEDLogoFilename = "logo_iped_azul.png"; + Dimension imgDimension = new Dimension(550, 200); + ImageIcon imgLogo = createNewButtonIcon(IPEDLogoFilename, imgDimension); + JLabel labelLogo = new JLabel(imgLogo, JLabel.CENTER); + labelLogo.addComponentListener(new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent e) { + if (labelLogo.getIcon() != null) { + int padding = 300; + // Image size proportion to calculate resize maintaining image proportion + double proportion = (imgDimension.getHeight() / imgDimension.getWidth()); + int newWidth = labelLogo.getWidth() - padding; + int maxWidht = 700; + newWidth = Math.min(maxWidht, newWidth); + double height = (newWidth * proportion); + Dimension resizedDimension = new Dimension(newWidth, (int) height); + labelLogo.setIcon(createNewButtonIcon(IPEDLogoFilename, resizedDimension)); + } + } + }); + GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + c.anchor = GridBagConstraints.PAGE_START; + c.weightx = 0.5; + c.weighty = 0.2; + c.gridx = 0; + c.gridy = 0; + c.gridwidth = 3; + c.gridheight = 1; + Insets inset = StyleManager.getDefaultPanelInsets(); + c.insets = new Insets(inset.top, inset.left, 2, inset.right); + this.add(labelLogo, c); + } + + /** + * Create and set up the application home buttons (new case, open case and + * config button) + */ + private void createAndSetupOptionsButtons() { + // default app inset + Insets inset = StyleManager.getDefaultPanelInsets(); + GridBagConstraints c = getOptionsButtonsGridBagConstraints(GridBagConstraints.LINE_START, 0, inset.left, 2); + this.add(getNewOptionsButton(Messages.get("Home.StartNewCase"), "newcase.png", MainFrameCardsNames.NEW_CASE), c); + c = getOptionsButtonsGridBagConstraints(GridBagConstraints.CENTER, 1, 2, 2); + this.add(getNewOptionsButton(Messages.get("Home.OpenCase"), "opencase.png", MainFrameCardsNames.OPEN_CASE), c); + c = getOptionsButtonsGridBagConstraints(GridBagConstraints.LINE_END, 2, 2, inset.right); + this.add(getNewOptionsButton(Messages.get("Home.Config"), "config.png", MainFrameCardsNames.CONFIG), c); + } + + /** + * Create a GridBagConstraints instance to be used with option buttons + * + * @param anchor + * - the item anchor positioning + * @param gridx + * - grid x positioning + * @return GridBagConstraints - A GridBagConstraints instance + */ + private GridBagConstraints getOptionsButtonsGridBagConstraints(int anchor, int gridx, int paddingLeft, int paddingRight) { + GridBagConstraints c = new GridBagConstraints(); + c.anchor = anchor; + c.fill = GridBagConstraints.BOTH; + c.weightx = 0.3; + c.weighty = 0.2; + c.gridx = gridx; + c.gridy = 1; + c.gridwidth = 1; + c.gridheight = 1; + c.insets = new Insets(2, paddingLeft, 100, paddingRight); + return c; + } + + /** + * Create a new JButton with default style and configuration for HomePanel + * + * @param buttonText + * - The text to be displayed on JButton + * @param iconName + * - The icon filename to be used on JButton + * @param destination + * - The card destination of button @see MainFrameCardsNames + * @return - a new JButton to be used as HomePanel Button + */ + private JButton getNewOptionsButton(String buttonText, String iconName, MainFrameCardsNames destination) { + JButton optionButton = new JButton(buttonText); + optionButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); + optionButton.setBorderPainted(false); + optionButton.setFocusable(false); + optionButton.setFont(StyleManager.getHomeButtonFont()); + // Button label alignment + optionButton.setVerticalTextPosition(SwingConstants.BOTTOM); + optionButton.setHorizontalTextPosition(SwingConstants.CENTER); + // set button click action + optionButton.addActionListener(e -> mainFrame.showPanel(destination)); + // set button icon with default size + optionButton.setIcon(createNewButtonIcon(iconName, new Dimension(152, 152))); + // A listener to resize button icon as size as panel size + optionButton.addComponentListener(new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent e) { + if (optionButton.getIcon() != null && optionButton.getIcon().getIconHeight() != optionButton.getHeight()) { + int padding = 110; + // we use the smaller button size to determine the icon size because the button + // not necessarily is redimensioned with same width and height + int iconSize = optionButton.getHeight() - padding; + iconSize = Math.min(iconSize, optionButton.getWidth()); + int maxIconSize = 200; + iconSize = Math.min(iconSize, maxIconSize); + Dimension resizedDimension = new Dimension(iconSize, iconSize); + optionButton.setIcon(createNewButtonIcon(iconName, resizedDimension)); + } + } + }); + return optionButton; + } + + /** + * create a new ImageIcon instance with proper size to the HomePanel + * + * @param imageFilename + * - The icon filename to be used on JButton + * @return ImageIcon - A new ImageIcon instance with proper size to the + * HomePanel + */ + private ImageIcon createNewButtonIcon(String imageFilename, Dimension iconDimension) { + ImageIcon icon = new ImageIcon(Objects.requireNonNull(getClass().getResource(imageFilename))); + Image resizedImage = icon.getImage().getScaledInstance(iconDimension.width, iconDimension.height, java.awt.Image.SCALE_SMOOTH); + return new ImageIcon(resizedImage); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/MainFrame.java b/iped-app/src/main/java/iped/app/home/MainFrame.java new file mode 100644 index 0000000000..a40e8aa783 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/MainFrame.java @@ -0,0 +1,187 @@ +package iped.app.home; + +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Toolkit; +import java.net.URL; + +import javax.swing.ImageIcon; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.ToolTipManager; +import javax.swing.WindowConstants; + +import iped.app.home.config.ConfigPanel; +import iped.app.home.newcase.NewCaseContainerPanel; +import iped.app.home.opencase.OpenCasePanel; +import iped.app.home.processmanager.ProcessManagerContainer; +import iped.app.home.style.StyleManager; +import iped.app.home.utils.CasePathManager; +import iped.app.ui.Messages; +import iped.app.ui.utils.UiScale; +import iped.engine.Version; +import iped.engine.config.Configuration; +import iped.engine.config.ConfigurationManager; +import iped.engine.config.LocaleConfig; +import iped.engine.task.ParsingTask; +import iped.engine.util.Util; +import iped.exception.UIException; +import iped.utils.ui.ScreenUtils; + +/** + * @created 02/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + * + * Home frame for IPED config and case start + */ +public class MainFrame extends JFrame { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private static MainFrame instance; + + private final JPanel cardsContentPanel = new JPanel(); + private ProcessManagerContainer pmc; + + public static synchronized MainFrame getInstance() { + if (instance == null) { + instance = new MainFrame(); + } + return instance; + } + + /** + * Class constructor + */ + private MainFrame() { + super(Version.APP_NAME); + } + + /** + * Validate and prepare application frame to be displayed + */ + private void createAndShowGUI() { + + try { + checkAppPreRequisites(); + setupLayout(); + } catch (Exception | UIException e) { + e.printStackTrace(); + JOptionPane.showMessageDialog(this, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); + System.exit(1); + } + + // show frame on first screen (if multiple monitors) + ScreenUtils.showOnScreen(0, this); + } + + /** + * Adjust layout configurations, sizes and behaviors + */ + private void setupLayout() throws Exception { + UiScale.loadUserSetting(); + this.setLayout(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.weightx = 1.0; + gbc.weighty = 1.0; + gbc.insets = StyleManager.getDefaultPanelInsets(); + gbc.anchor = GridBagConstraints.CENTER; + gbc.fill = GridBagConstraints.BOTH; + cardsContentPanel.setBackground(Color.white); + cardsContentPanel.setLayout(new CardLayout()); + this.add(cardsContentPanel, gbc); + + // Load configurables files + Configuration configuration = Configuration.getInstance(); + Configuration.getInstance().saveIpedRoot(CasePathManager.getInstance().getConfigPath().getAbsolutePath()); + configuration.loadConfigurables(CasePathManager.getInstance().getConfigPath().getAbsolutePath(), true); + + // Add panels to cardlayout + cardsContentPanel.add(new HomePanel(this), MainFrameCardsNames.HOME.getName()); + cardsContentPanel.add(new ConfigPanel(this), MainFrameCardsNames.CONFIG.getName()); + cardsContentPanel.add(new NewCaseContainerPanel(this), MainFrameCardsNames.NEW_CASE.getName()); + cardsContentPanel.add(new OpenCasePanel(this), MainFrameCardsNames.OPEN_CASE.getName()); + + ParsingTask.setupParsingOptions(ConfigurationManager.get()); + + setHomeFrameSize(); + setFrameIcon(); + + // set tooltip delay + ToolTipManager.sharedInstance().setDismissDelay(15000); + + // Dark Theme is still not working properly with config UI... + // ThemeManager.getInstance().setLookAndFeel(); + + // Set the locale used for docking frames, so texts and tool tips are localized + // (if available) + LocaleConfig localeConfig = ConfigurationManager.get().findObject(LocaleConfig.class); + // Set the locale used by JFileChooser's + JFileChooser.setDefaultLocale(localeConfig.getLocale()); + } + + /** + * Check if all requisites to show frame are present + */ + private void checkAppPreRequisites() throws UIException { + // check JavaFX + if (!Util.isJavaFXPresent()) { + throw new UIException(Messages.get("NoJavaFX.Error")); + } + } + + /** + * Set application frame Icon + */ + private void setFrameIcon() { + // set frame icon + URL image = getClass().getResource("search.png"); //$NON-NLS-1$ + assert image != null; + this.setIconImage(new ImageIcon(image).getImage()); + } + + /** + * Set Home frame size + */ + private void setHomeFrameSize() { + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + Dimension preferredSize = new Dimension(1280, 1024); + Dimension minimumSize = new Dimension(1024, 768); + this.setPreferredSize(preferredSize); + this.setMinimumSize(minimumSize); + this.setMaximumSize(screenSize); + } + + /** + * Manage the panel to be displayed on MainFrame based on card name this method + * is used by other class to navigate, don't change de public accessor method + * + * @param cardName + * - Card name of JPanel to be displayed + */ + public void showPanel(MainFrameCardsNames cardName) { + ((CardLayout) cardsContentPanel.getLayout()).show(cardsContentPanel, cardName.getName()); + } + + /** + * Application Start point + */ + public static void main(String[] args) { + SwingUtilities.invokeLater(() -> { + MainFrame main = MainFrame.getInstance(); + main.createAndShowGUI(); + main.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + }); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/MainFrameCardsNames.java b/iped-app/src/main/java/iped/app/home/MainFrameCardsNames.java new file mode 100644 index 0000000000..b9b0bcf6b0 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/MainFrameCardsNames.java @@ -0,0 +1,37 @@ +package iped.app.home; + +/* + * @created 07/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +/** + * A List of Cards Name to be used on MainFrame "CardLayout" Layout manager + */ +public enum MainFrameCardsNames { + + HOME(0, "HOME"), CONFIG(1, "CONFIG"), NEW_CASE(2, "NEW_CASE"), OPEN_CASE(3, "OPEN_CASE"), PROCESS_MANAGER(4, "PROCESS_MANAGER"), TASK_CONFIG(5, "TASK_CONFIG"); + + private final int value; + private final String name; + + MainFrameCardsNames(final int value, final String name) { + this.value = value; + this.name = name; + } + + public int getValue() { + return value; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return getName(); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/config/ConfigPanel.java b/iped-app/src/main/java/iped/app/home/config/ConfigPanel.java new file mode 100644 index 0000000000..e430d85d67 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/config/ConfigPanel.java @@ -0,0 +1,501 @@ +package iped.app.home.config; + +import java.awt.Color; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Image; +import java.awt.Insets; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.ItemEvent; +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Objects; + +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.DefaultComboBoxModel; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JSpinner; +import javax.swing.JTextField; +import javax.swing.filechooser.FileNameExtensionFilter; +import javax.swing.filechooser.FileSystemView; + +import org.apache.commons.lang.SystemUtils; + +/* + * @created 07/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import iped.app.home.DefaultPanel; +import iped.app.home.MainFrame; +import iped.app.home.MainFrameCardsNames; +import iped.app.home.configurables.AutoCalcSpinnerModel; +import iped.app.home.style.StyleManager; +import iped.app.home.utils.CasePathManager; +import iped.app.ui.Messages; +import iped.configuration.IConfigurationDirectory; +import iped.engine.config.ConfigurationManager; +import iped.engine.config.LocalConfig; +import iped.engine.config.LocaleConfig; +import iped.engine.config.PluginConfig; +import iped.engine.config.ProfileManager; + +/** + * Her we'll manage IPED configuration the main config file is LocalConfig.txt + */ +public class ConfigPanel extends DefaultPanel { + + private JSpinner spinnerThreads; + private JButton buttonSetDefaultThread; + private JTextField textFieldIndexTemp; + private JButton buttonChangeIndexTempPath; + private JButton buttonSetDefaultIndexTempPath; + + private JCheckBox checkBoxIndexTempOnSSD; + private JTextField textFieldHashesDB; + private JButton buttonChangeHashDB; + private JCheckBox checkBoxEnableDisableHashDb; + private JTextField textFieldTskJarPath; + private JButton buttonChangeTskJarPath; + + private JTextField textFieldPluginFolder; + private JComboBox comboBoxLocale; + private JButton buttonChangePluginConfig; + private Boolean RUNNIG_ON_WINDOWS; + + private boolean isEnableHashDB; + + private ConfigurationManager defaultConfigurationManager; + + /** + * Default Constructor + * + * @param mainFrame + * - Application MainFrame Reference + */ + public ConfigPanel(MainFrame mainFrame) { + super(mainFrame); + } + + /** + * Prepare everything to be displayed + */ + protected void createAndShowGUI() { + ProfileManager.get().addObject(ProfileManager.get().getDefaultProfile()); + defaultConfigurationManager = ConfigurationManager.get(); + // A listener to force components to load values from file. So if user change + // values but do not save, whe will load the original properties and discard + // user changes + this.addComponentListener(new ComponentAdapter() { + public void componentShown(ComponentEvent e) { + updateComponentsState(); + } + }); + + this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); + this.add(createTitlePanel()); + this.add(createFormPanel()); + this.add(Box.createVerticalGlue()); + this.add(createButtonsPanel()); + } + + /** + * Create a new JPanel instance containing the Page Title + * + * @return - JPanel containing the Page Title + */ + private JPanel createTitlePanel() { + JPanel panelTitle = new JPanel(); + panelTitle.setBackground(super.getCurrentBackGroundColor()); + + JLabel labelTitle = new JLabel(Messages.get("Home.LocalEnviromentConfiguration")); + labelTitle.setFont(StyleManager.getPageTitleFont()); + panelTitle.add(labelTitle); + return panelTitle; + } + + /** + * Create instance to form components and set default behavior + */ + private void createFormComponentInstances() { + // Default icons to use on JFileChooser + String ICON_OPEN_FOLDER = "cat/Folders.png"; + String ICON_SET_DEFAULT = "cat/Internet History.png"; + // A variable to check if the app is runnong on Windows. You can use to test the + // Linux behavior + RUNNIG_ON_WINDOWS = SystemUtils.IS_OS_WINDOWS; + + // Create combobox to select Languages + comboBoxLocale = new JComboBox<>(new DefaultComboBoxModel<>(Languages.values())); + comboBoxLocale.setRenderer(new LanguageComboBoxCellRender()); + + // Create JSpinner to change the number of Threads and a button to set the + // default thread value + spinnerThreads = new JSpinner(); + spinnerThreads.setModel(new AutoCalcSpinnerModel(spinnerThreads, LocalConfig.DEFAULT_VAL)); + ((JSpinner.DefaultEditor) spinnerThreads.getEditor()).getTextField().setEditable(false); + buttonSetDefaultThread = getNewIconButton(ICON_SET_DEFAULT); + buttonSetDefaultThread.setToolTipText(Messages.get("Home.DefaultThreadValue")); + buttonSetDefaultThread.addActionListener(e -> spinnerThreads.setValue(Runtime.getRuntime().availableProcessors())); + + // Create a TextField to show the IndexTemp Path, a JButton to select a new + // IndexPath location and a JButton to set the Default indexPath Value + textFieldIndexTemp = new JTextField(); + textFieldIndexTemp.setEditable(false); + buttonChangeIndexTempPath = getNewIconButton(ICON_OPEN_FOLDER); + buttonChangeIndexTempPath.addActionListener(e -> { + File selectedFile = showDirectoryFileChooser(Messages.get("Home.ChooseDefaultIndexTempFolder"), null); + textFieldIndexTemp.setText(selectedFile != null ? selectedFile.toPath().toString() : ""); + }); + buttonSetDefaultIndexTempPath = getNewIconButton(ICON_SET_DEFAULT); + buttonSetDefaultIndexTempPath.setToolTipText(Messages.get("Home.DefaultIndexTempToolTip")); + buttonSetDefaultIndexTempPath.addActionListener(e -> textFieldIndexTemp.setText("default")); + + // Create a CheckBox to set indexTempOnSSD propertie (Only true or false) + checkBoxIndexTempOnSSD = new JCheckBox(Messages.get("Home.IndexTempOnSSDLabel")); + checkBoxIndexTempOnSSD.setBackground(super.getCurrentBackGroundColor()); + + // Create a TextField to show the HashDBFile Path, a JButton to select a new + // HashDBFile location and a CheckBox to enable or disable this option + textFieldHashesDB = new JTextField(); + textFieldHashesDB.setEditable(false); + buttonChangeHashDB = getNewIconButton(ICON_OPEN_FOLDER); + buttonChangeHashDB.addActionListener(e -> { + File selectedFile = showFileChooser(Messages.get("Home.InformHashDBFile"), "hashes.db", new String[] { "db", "DB" }, Messages.get("Home.Select")); + textFieldHashesDB.setText(selectedFile != null ? selectedFile.getAbsolutePath() : textFieldHashesDB.getText()); + }); + checkBoxEnableDisableHashDb = new JCheckBox(Messages.get("Home.Active")); + checkBoxEnableDisableHashDb.setBackground(super.getCurrentBackGroundColor()); + checkBoxEnableDisableHashDb.addItemListener(e -> { + isEnableHashDB = (e.getStateChange() == ItemEvent.SELECTED); + checkBoxEnableDisableHashDb.setText(isEnableHashDB ? Messages.get("Home.Active") : Messages.get("Home.Inactive")); + buttonChangeHashDB.setVisible(isEnableHashDB); + Color tfBackground = textFieldHashesDB.getBackground(); + textFieldHashesDB.setEnabled(isEnableHashDB); + textFieldHashesDB.setBackground(tfBackground); + defaultConfigurationManager.reloadConfigurable(LocalConfig.class); + }); + + // Create a TextField to show TSKJar Path and a button to select a new TSKJar + // Path + // Attention -- This TextField can be showed or hide based on operational system + // in use. This behavior is controlled by createFormPanel() method + textFieldTskJarPath = new JTextField(); + textFieldTskJarPath.setEditable(false); + buttonChangeTskJarPath = getNewIconButton(ICON_OPEN_FOLDER); + buttonChangeTskJarPath.addActionListener(e -> { + File selectedFile = showFileChooser(Messages.get("Home.TSKJarDialogTtitle"), "sleuthkit-x.x.x.jar", new String[] { "jar", "JAR" }, Messages.get("Home.Select")); + textFieldTskJarPath.setText(selectedFile != null ? selectedFile.getAbsolutePath() : ""); + }); + + // Create a TextField to show the Option Plugin Path and a Button to select a + // new one + // Attention -- When user select a new path, we save the relative path and not + // the absolute path + textFieldPluginFolder = new JTextField(); + textFieldPluginFolder.setEditable(false); + buttonChangePluginConfig = getNewIconButton(ICON_OPEN_FOLDER); + // A listener to convert Absolute path in relative path based on Iped App root + buttonChangePluginConfig.addActionListener(e -> { + String appRoot = System.getProperty(IConfigurationDirectory.IPED_APP_ROOT); + Path basePath = Paths.get(appRoot); + File selectedFile = showDirectoryFileChooser(Messages.get("Home.OptPluginDialogTtitle"), basePath.getParent().toFile()); + if (selectedFile == null) + return; + Path relativePath = basePath.relativize(selectedFile.toPath()); + PluginConfig pluginConfig = defaultConfigurationManager.findObject(PluginConfig.class); + pluginConfig.setPluginFolder(relativePath.toString()); + textFieldPluginFolder.setText(relativePath.toString()); + }); + + } + + /** + * A form JButton factory + * + * @param iconResourceString + * - Icon resource reference + * @return A JButton instance with the icon + */ + private JButton getNewIconButton(String iconResourceString) { + ImageIcon icon = new ImageIcon(Objects.requireNonNull(iped.app.ui.App.class.getResource(iconResourceString))); + Image resizedImage = icon.getImage().getScaledInstance(15, 15, java.awt.Image.SCALE_SMOOTH); + JButton button = new JButton(); + button.setIcon(new ImageIcon(resizedImage)); + return button; + } + + /** + * A JFiledChoose Factory with the proper behavior to select Directories only + * + * @param title + * - File Chooser Title + * @param baseDirectory + * - The base Path to be showed + * @return - A File instance containing the path selected by user + */ + private File showDirectoryFileChooser(String title, File baseDirectory) { + JFileChooser fileChooserDestino = new JFileChooser(baseDirectory != null ? baseDirectory : FileSystemView.getFileSystemView().getHomeDirectory()); + fileChooserDestino.setDialogTitle(title); + fileChooserDestino.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + fileChooserDestino.setAcceptAllFileFilterUsed(false); + if (fileChooserDestino.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { + return fileChooserDestino.getSelectedFile(); + } + return null; + } + + /** + * @param title + * - File Chooser Title + * @param fileFilterName + * - Name of the filter + * @param filters + * - The filters values + * @param buttonName + * - Select file button name + * @return The File selected by the user + */ + private File showFileChooser(String title, String fileFilterName, String[] filters, String buttonName) { + JFileChooser fileChooser = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory()); + fileChooser.setDialogTitle(title); + fileChooser.setAcceptAllFileFilterUsed(false); + FileNameExtensionFilter filter = new FileNameExtensionFilter(fileFilterName, filters); + fileChooser.addChoosableFileFilter(filter); + int returnValue = fileChooser.showDialog(this, buttonName); + if (returnValue == JFileChooser.APPROVE_OPTION) { + return fileChooser.getSelectedFile(); + } + return null; + } + + /** + * Create a new JPanel instance containing all inputs + * + * @return JPanel - A JPanel containing all data input form itens + */ + private JPanel createFormPanel() { + JPanel panelForm = new JPanel(new GridBagLayout()); + panelForm.setBackground(super.getCurrentBackGroundColor()); + + createFormComponentInstances(); + + int labelCellColumnWidth = 1; + double labelsWeightsX = 0; + double inputsWeightsX = 1.0; + int linha = 0; + + panelForm.add(new JLabel(Messages.get("Home.Language") + ":"), getGridBagConstraints(0, linha, 1, labelsWeightsX)); + panelForm.add(comboBoxLocale, getGridBagConstraints(1, linha, 1, inputsWeightsX)); + + panelForm.add(new JLabel(Messages.get("Home.NumberOfThreads") + ":"), getGridBagConstraints(2, linha, 1, labelsWeightsX)); + JPanel buttonsPanel = getComponentsPanel(spinnerThreads, buttonSetDefaultThread); + panelForm.add(buttonsPanel, getGridBagConstraints(3, linha, 1, 0)); + + linha++; + panelForm.add(new JLabel(Messages.get("Home.TempFolder") + ":"), getGridBagConstraints(0, linha, 1, labelsWeightsX)); + panelForm.add(textFieldIndexTemp, getGridBagConstraints(1, linha, 2, 0.5)); + buttonsPanel = getComponentsPanel(buttonChangeIndexTempPath, buttonSetDefaultIndexTempPath); + panelForm.add(buttonsPanel, getGridBagConstraints(3, linha, 1, 0)); + + linha++; + panelForm.add(checkBoxIndexTempOnSSD, getGridBagConstraints(0, linha, 3, labelsWeightsX)); + + linha++; + panelForm.add(new JLabel(Messages.get("Home.HashDatabase") + ":"), getGridBagConstraints(0, linha, labelCellColumnWidth, labelsWeightsX)); + panelForm.add(textFieldHashesDB, getGridBagConstraints(1, linha, 2, inputsWeightsX)); + buttonsPanel = getComponentsPanel(buttonChangeHashDB, checkBoxEnableDisableHashDb); + panelForm.add(buttonsPanel, getGridBagConstraints(3, linha, 1, 0)); + + // On Linux whe need to set the TSK Jar Path + if (!RUNNIG_ON_WINDOWS) { + linha++; + panelForm.add(new JLabel(Messages.get("Home.TSKJar") + ":"), getGridBagConstraints(0, linha, labelCellColumnWidth, labelsWeightsX)); + panelForm.add(textFieldTskJarPath, getGridBagConstraints(1, linha, 2, inputsWeightsX)); + buttonsPanel = getComponentsPanel(buttonChangeTskJarPath); + panelForm.add(buttonsPanel, getGridBagConstraints(3, linha, 1, 0)); + } + + linha++; + panelForm.add(new JLabel(Messages.get("Home.OptionalPluginsPath") + ":"), getGridBagConstraints(0, linha, labelCellColumnWidth, labelsWeightsX)); + panelForm.add(textFieldPluginFolder, getGridBagConstraints(1, linha, 2, inputsWeightsX)); + buttonsPanel = getComponentsPanel(buttonChangePluginConfig); + panelForm.add(buttonsPanel, getGridBagConstraints(3, linha, 1, 0)); + + return panelForm; + } + + /** + * A simple method to create a JPanel to wrapp all components + * + * @param components + * - List of components to be added on JPanel + * @return A Jpanel with all components + */ + private JPanel getComponentsPanel(JComponent... components) { + JPanel buttonsPanel = new JPanel(); + buttonsPanel.setBackground(super.getCurrentBackGroundColor()); + for (JComponent button : components) + buttonsPanel.add(button); + return buttonsPanel; + } + + /** + * Create a new GridBagConstraints to be used on this page Form + * + * @param tableColumnIndex + * - The index number of table column + * @param tableLineIndex + * - The index number of table line + * @param cellWidth + * - The table Cell Width + * @param weightX + * - Cell Weight X + * @return GridBagConstraints - a new GridBagConstraints instance containing all + * parameter passed + */ + private GridBagConstraints getGridBagConstraints(int tableColumnIndex, int tableLineIndex, int cellWidth, double weightX) { + GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = weightX; + c.gridx = tableColumnIndex; + c.gridy = tableLineIndex; + c.gridwidth = cellWidth; + c.gridheight = 1; + c.insets = new Insets(2, 10, 2, 10); + return c; + } + + /** + * A JPanel containing "Save" and "Cancel" buttons + * + * @return JPanel - a new JPanel instance containing the bottom page Button + */ + private JPanel createButtonsPanel() { + JPanel panelButtons = new JPanel(); + panelButtons.setBackground(super.getCurrentBackGroundColor()); + JButton buttonSave = new JButton(Messages.get("Home.Save")); + buttonSave.addActionListener(e -> saveConfiguration()); + JButton buttonCancel = new JButton(Messages.get("Home.Cancel")); + buttonCancel.addActionListener(e -> mainFrame.showPanel(MainFrameCardsNames.HOME)); + panelButtons.add(buttonSave); + panelButtons.add(buttonCancel); + return panelButtons; + } + + public void updateComponentsState() { + updateLocaleConfigComponentsState(); + updateLocalConfigComponentsState(); + updatePluginConfigComponentsState(); + } + + private void updateLocaleConfigComponentsState() { + // Load configs Files. Please do not create a global variable for Configurables + // objects + LocaleConfig localeConfig = defaultConfigurationManager.findObject(LocaleConfig.class); + // set values to input texts + String languageTag = (localeConfig.getLocale() != null) ? localeConfig.getLocale().toLanguageTag() : ""; + comboBoxLocale.setSelectedItem(Languages.getByLanguageTag(languageTag)); + } + + private void updateLocalConfigComponentsState() { + defaultConfigurationManager.reloadConfigurable(LocalConfig.class); + LocalConfig localConfig = defaultConfigurationManager.findObject(LocalConfig.class); + spinnerThreads.setValue(localConfig.getPropertie().getProperty(LocalConfig.NUM_THREADS)); + textFieldIndexTemp.setText((localConfig.getPropertie().getProperty(LocalConfig.IPED_TEMP) == null) ? "Default" : localConfig.getPropertie().getProperty(LocalConfig.IPED_TEMP)); + checkBoxIndexTempOnSSD.setSelected(localConfig.isIndexTempOnSSD()); + File hashDbFile = localConfig.getHashDbFile(); + boolean isHashDBEnabled = hashDbFile != null; + if (hashDbFile == null) { + // load commented out hashedDb path from txt file + localConfig.getPropertie().enableOrDisablePropertie(CasePathManager.getInstance().getLocalConfigFile(), LocalConfig.HASH_DB, false); + defaultConfigurationManager.reloadConfigurable(LocalConfig.class); + localConfig = defaultConfigurationManager.findObject(LocalConfig.class); + hashDbFile = localConfig.getHashDbFile(); + localConfig.getPropertie().enableOrDisablePropertie(CasePathManager.getInstance().getLocalConfigFile(), LocalConfig.HASH_DB, true); + } + textFieldHashesDB.setText(hashDbFile != null ? hashDbFile.getAbsolutePath() : ""); + Color tfBackground = textFieldHashesDB.getBackground(); + textFieldHashesDB.setEnabled(isEnableHashDB); + textFieldHashesDB.setBackground(tfBackground); + + checkBoxEnableDisableHashDb.setSelected(isHashDBEnabled); + checkBoxEnableDisableHashDb.setText(isHashDBEnabled ? Messages.get("Home.Active") : Messages.get("Home.Inactive")); + buttonChangeHashDB.setVisible(isHashDBEnabled); + } + + private void updatePluginConfigComponentsState() { + PluginConfig pluginConfig = defaultConfigurationManager.findObject(PluginConfig.class); + if (!RUNNIG_ON_WINDOWS) { + if (!pluginConfig.isTskJarPathEnabled()) { + pluginConfig.getPropertie().enableOrDisablePropertie(CasePathManager.getInstance().getLocalConfigFile(), PluginConfig.TSK_JAR_PATH, false); + defaultConfigurationManager.reloadConfigurable(PluginConfig.class); + pluginConfig = defaultConfigurationManager.findObject(PluginConfig.class); + } + textFieldTskJarPath.setText((pluginConfig.getTskJarFile() != null) ? pluginConfig.getTskJarFile().getAbsolutePath() : ""); + } + textFieldPluginFolder.setText((pluginConfig.getRelativePluginFolder() != null) ? pluginConfig.getRelativePluginFolder() : ""); + } + + /** + * Save all changes made by user + */ + private void saveConfiguration() { + try { + // Save LocaleConfig + LocaleConfig localeConfig = defaultConfigurationManager.findObject(LocaleConfig.class); + Languages selectedLanguage = ((Languages) comboBoxLocale.getSelectedItem()); + if (!localeConfig.getLocale().toLanguageTag().equals(selectedLanguage.getLanguageTag())) { + JOptionPane.showMessageDialog(this, Messages.get("Home.LanguageChangeMessage"), Messages.get("Home.LanguageChangeTitle"), JOptionPane.WARNING_MESSAGE); + } + localeConfig.setLocale(selectedLanguage.getLanguageTag()); + localeConfig.getPropertie().saveOnFile(CasePathManager.getInstance().getLocalConfigFile()); + + // Force LocalConfig to reload possible changes made by LocaleConfig + defaultConfigurationManager.reloadConfigurable(LocalConfig.class); + LocalConfig localConfig = defaultConfigurationManager.findObject(LocalConfig.class); + // Set changes on LocalConfig Configurable class + localConfig.setIndexTempOnSSD(checkBoxIndexTempOnSSD.isSelected()); + localConfig.getPropertie().setProperty(LocalConfig.IPED_TEMP, textFieldIndexTemp.getText()); + localConfig.setNumThreads(spinnerThreads.getValue()); + localConfig.getPropertie().setProperty(LocalConfig.HASH_DB, textFieldHashesDB.getText()); + localConfig.getPropertie().enableOrDisablePropertie(CasePathManager.getInstance().getLocalConfigFile(), LocalConfig.HASH_DB, !isEnableHashDB); + // Save LocalConfig modifications to file + localConfig.getPropertie().saveOnFile(CasePathManager.getInstance().getLocalConfigFile()); + + // Force PluginConfig to reload possible changes made by LocalConfig + defaultConfigurationManager.reloadConfigurable(PluginConfig.class); + PluginConfig pluginConfig = defaultConfigurationManager.findObject(PluginConfig.class); + // Set changes on PluginConfig Configurable class + pluginConfig.setPluginFolder(textFieldPluginFolder.getText()); + if (!RUNNIG_ON_WINDOWS) { + if ((textFieldTskJarPath.getText() == null) || (!textFieldTskJarPath.getText().trim().isEmpty())) + pluginConfig.setTskJarFile(textFieldTskJarPath.getText() != null ? textFieldTskJarPath.getText().trim() : null); + } + pluginConfig.getPropertie().saveOnFile(CasePathManager.getInstance().getLocalConfigFile()); + + // Force LocalConfig to reload changes made by PluginConfig + defaultConfigurationManager.reloadConfigurable(LocalConfig.class); + defaultConfigurationManager.reloadConfigurable(PluginConfig.class); + + } catch (IOException e) { + e.printStackTrace(); + JOptionPane.showMessageDialog(this, e.toString(), "Error", JOptionPane.ERROR_MESSAGE); + } + mainFrame.showPanel(MainFrameCardsNames.HOME); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/config/LanguageComboBoxCellRender.java b/iped-app/src/main/java/iped/app/home/config/LanguageComboBoxCellRender.java new file mode 100644 index 0000000000..b3fff17dbc --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/config/LanguageComboBoxCellRender.java @@ -0,0 +1,24 @@ +package iped.app.home.config;/* + * @created 26/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import java.awt.Component; + +import javax.swing.DefaultListCellRenderer; +import javax.swing.JList; + +public class LanguageComboBoxCellRender extends DefaultListCellRenderer { + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + if (value instanceof Languages) { + Languages person = (Languages) value; + setText(person.getDescription() + " (" + person.getLanguageTag() + ")"); + } + return this; + } + +} diff --git a/iped-app/src/main/java/iped/app/home/config/Languages.java b/iped-app/src/main/java/iped/app/home/config/Languages.java new file mode 100644 index 0000000000..2d85fcd2d3 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/config/Languages.java @@ -0,0 +1,69 @@ +package iped.app.home.config;/* + * @created 22/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import java.util.ArrayList; +import java.util.Arrays; + +import iped.app.ui.Messages; + +public enum Languages { + + PT_BR(0, Messages.get("Home.LanguagePtBR"), "pt-BR"), EN(1, Messages.get("Home.LanguageEN"), "en"), IT(2, Messages.get("Home.LanguageIT"), "it-IT"), DE(3, Messages.get("Home.LanguageDE"), "de-DE"), ES(4, + Messages.get("Home.LanguageEsAr"), "es-AR"); + + private int value; + private String description; + private String languageTag; + + Languages(int value, String description, String languageTag) { + this.value = value; + this.description = description; + this.languageTag = languageTag; + } + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getLanguageTag() { + return languageTag; + } + + public void setLanguageTag(String languageTag) { + this.languageTag = languageTag; + } + + public static ArrayList getListOfDescription() { + ArrayList listOfDescriptions = new ArrayList<>(); + Arrays.stream(Languages.values()).forEach(languages -> listOfDescriptions.add(languages.getDescription())); + return listOfDescriptions; + } + + public static Languages getByLanguageTag(String languageTag) { + for (Languages language : Languages.values()) { + if (language.getLanguageTag().equalsIgnoreCase(languageTag)) + return language; + } + return null; + } + + @Override + public String toString() { + return description; + } +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/AdvancedTextConfigurablePanel.java b/iped-app/src/main/java/iped/app/home/configurables/AdvancedTextConfigurablePanel.java new file mode 100644 index 0000000000..e77d9ec19d --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/AdvancedTextConfigurablePanel.java @@ -0,0 +1,133 @@ +package iped.app.home.configurables; + +import java.awt.Component; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyVetoException; +import java.beans.VetoableChangeListener; +import java.beans.VetoableChangeSupport; + +import javax.swing.DefaultSingleSelectionModel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.UIManager; +import javax.swing.event.ChangeEvent; +import javax.swing.plaf.basic.BasicTabbedPaneUI; + +import iped.app.home.MainFrame; +import iped.app.home.configurables.api.ConfigurableValidationException; +import iped.app.ui.Messages; +import iped.configuration.Configurable; + +public abstract class AdvancedTextConfigurablePanel extends TextConfigurablePanel { + protected JTabbedPane tabbedPane; + protected JPanel basicPanel; + private VetoableSingleSelectionModel tabModel; + + protected AdvancedTextConfigurablePanel(Configurable configurable, MainFrame mainFrame) { + super(configurable, mainFrame); + tabbedPane = new JTabbedPane(JTabbedPane.BOTTOM); + tabModel = new VetoableSingleSelectionModel(this); + tabbedPane.setModel(tabModel); + tabbedPane.setUI(new BasicTabbedPaneUI() { + @Override + protected int calculateTabHeight(int tabPlacement, int tabIndex, int fontHeight) { + return 25; + } + + }); + } + + /** + * selection model that implement tab vetoable change listeners that avoid tab + * change if configuration state is not valid. From + * https://stackoverflow.com/questions/12389801/forbid-tab-change-in-a-jtabbedpane + */ + public static class VetoableSingleSelectionModel extends DefaultSingleSelectionModel { + private VetoableChangeSupport vetoableChangeSupport; + AdvancedTextConfigurablePanel componentSource; + + public VetoableSingleSelectionModel(AdvancedTextConfigurablePanel componentSource) { + this.componentSource = componentSource; + } + + @Override + public void setSelectedIndex(int index) { + if (getSelectedIndex() == index) + return; + try { + fireVetoableChange(getSelectedIndex(), index); + } catch (PropertyVetoException e) { + JOptionPane.showMessageDialog(componentSource, e.getMessage()); + + return; + } + super.setSelectedIndex(index); + } + + private void fireVetoableChange(int oldSelectionIndex, int newSelectionIndex) throws PropertyVetoException { + if (!isVetoable()) + return; + vetoableChangeSupport.fireVetoableChange("selectedIndex", oldSelectionIndex, newSelectionIndex); + + } + + private boolean isVetoable() { + if (vetoableChangeSupport == null) + return false; + return vetoableChangeSupport.hasListeners(null); + } + + public void addVetoableChangeListener(VetoableChangeListener l) { + if (vetoableChangeSupport == null) { + vetoableChangeSupport = new VetoableChangeSupport(this); + } + vetoableChangeSupport.addVetoableChangeListener(l); + } + + public void removeVetoableChangeListener(VetoableChangeListener l) { + if (vetoableChangeSupport == null) + return; + vetoableChangeSupport.removeVetoableChangeListener(l); + } + } + + public void createConfigurableGUI() { + super.createConfigurableGUI(); + + this.remove(txtAreaScroll); + + tabbedPane.addTab(getBasicPaneTitle(), UIManager.getIcon("FileView.fileIcon"), getBasicPane(), ""); + tabbedPane.addTab(Messages.get("Home.configurables.AdvancedPanelLabel"), UIManager.getIcon("FileView.fileIcon"), txtAreaScroll, ""); + this.add(tabbedPane); + + tabbedPane.getModel().addChangeListener(null); + + AdvancedTextConfigurablePanel self = this; + + tabModel.addVetoableChangeListener(new VetoableChangeListener() { + + @Override + public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException { + if (self.hasChanged()) { + try { + self.applyChanges(); + changed = false; + fireChangeListener(new ChangeEvent(this)); + } catch (ConfigurableValidationException cve) { + JOptionPane.showMessageDialog(self, cve.getMessage() + "\n" + cve.getCause(), "", JOptionPane.ERROR_MESSAGE); + PropertyVetoException pve = new PropertyVetoException("Change not valid", evt); + throw pve; + } + } + } + }); + + } + + protected String getBasicPaneTitle() { + return Messages.get("Home.configurables.BasicPanelLabel"); + } + + protected abstract Component getBasicPane(); +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/AutoCalcSpinnerModel.java b/iped-app/src/main/java/iped/app/home/configurables/AutoCalcSpinnerModel.java new file mode 100644 index 0000000000..eaff63495c --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/AutoCalcSpinnerModel.java @@ -0,0 +1,121 @@ +package iped.app.home.configurables; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Iterator; + +import javax.swing.AbstractSpinnerModel; +import javax.swing.JFormattedTextField; +import javax.swing.JFormattedTextField.AbstractFormatter; +import javax.swing.JFormattedTextField.AbstractFormatterFactory; +import javax.swing.JSpinner; +import javax.swing.JSpinner.DefaultEditor; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +public class AutoCalcSpinnerModel extends AbstractSpinnerModel { + int value; + JSpinner spinner; + ArrayList listeners = new ArrayList(); + private boolean isInternalChage; + + String autoString = "auto"; + + public AutoCalcSpinnerModel(JSpinner spinner, String autoString) { + this(spinner); + this.autoString = autoString; + } + + public AutoCalcSpinnerModel(JSpinner spinner) { + this.spinner = spinner; + DefaultEditor c = new DefaultEditor(spinner); + c.getTextField().setEditable(true); + c.getTextField().setEnabled(true); + c.setEnabled(true); + c.getTextField().setFormatterFactory(new AbstractFormatterFactory() { + @Override + public AbstractFormatter getFormatter(JFormattedTextField tf) { + // TODO Auto-generated method stub + return new AbstractFormatter() { + @Override + public String valueToString(Object value) throws ParseException { + return value.toString(); + } + + @Override + public Object stringToValue(String text) throws ParseException { + if (text.equals("0") || text.trim().equals("")) { + return autoString; + } + return text; + } + }; + } + }); + // spinner.setEditor(); + spinner.setEditor(c); + } + + @Override + public Object getValue() { + if (value == 0) { + return autoString; + } else { + return value; + } + } + + @Override + public void setValue(Object value) { + boolean valid = true; + if (value.toString().equals(autoString)) { + this.value = 0; + } else { + if (value instanceof String) { + try { + this.value = Integer.parseInt((String) value); + } catch (Exception e) { + valid = false; + } + } else { + this.value = (Integer) value; + } + } + if (!isInternalChage) { + DefaultEditor c = (DefaultEditor) spinner.getEditor(); + isInternalChage = true; + c.getTextField().setValue(getValue()); + isInternalChage = false; + if (valid) { + for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { + ChangeListener changeListener = (ChangeListener) iterator.next(); + changeListener.stateChanged(new ChangeEvent(spinner)); + } + } + } + } + + @Override + public Object getNextValue() { + return value + 1; + } + + @Override + public Object getPreviousValue() { + if (value > 0) { + return value - 1; + } + return 0; + } + + @Override + public void addChangeListener(ChangeListener l) { + listeners.add(l); + } + + @Override + public void removeChangeListener(ChangeListener l) { + listeners.remove(l); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/CarverConfigCellRenderer.java b/iped-app/src/main/java/iped/app/home/configurables/CarverConfigCellRenderer.java new file mode 100644 index 0000000000..b113e064f1 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/CarverConfigCellRenderer.java @@ -0,0 +1,39 @@ +package iped.app.home.configurables; + +import java.awt.BorderLayout; +import java.awt.Component; + +import javax.swing.JCheckBox; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.ListCellRenderer; + +import iped.carvers.api.CarverType; + +public class CarverConfigCellRenderer extends JPanel implements ListCellRenderer { + JCheckBox enabledCheckBox = new JCheckBox(); + int maxStringWidth = 0; + + public CarverConfigCellRenderer() { + this.setLayout(new BorderLayout()); + add(enabledCheckBox, BorderLayout.CENTER); + } + + @Override + public Component getListCellRendererComponent(JList list, CarverType ct, int index, boolean isSelected, boolean cellHasFocus) { + enabledCheckBox.setSelected(ct.isEnabled()); + enabledCheckBox.setText(ct.getName()); + + this.add(enabledCheckBox, BorderLayout.CENTER); + + return this; + } + + public int getMaxStringWidth() { + if (maxStringWidth < enabledCheckBox.getWidth()) { + maxStringWidth = enabledCheckBox.getWidth(); + } + return maxStringWidth; + } + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/CategorySetConfigPanel.java b/iped-app/src/main/java/iped/app/home/configurables/CategorySetConfigPanel.java new file mode 100644 index 0000000000..c14aa4267a --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/CategorySetConfigPanel.java @@ -0,0 +1,85 @@ +package iped.app.home.configurables; + +import java.awt.BorderLayout; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import javax.swing.JScrollPane; +import javax.swing.JTree; +import javax.swing.ScrollPaneConstants; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import com.google.common.base.Predicate; + +import iped.app.home.MainFrame; +import iped.app.home.configurables.api.ConfigurableValidationException; +import iped.app.ui.CategoryMimeTreeModel; +import iped.app.ui.controls.ConfigCheckBoxTreeCellRenderer; +import iped.configuration.Configurable; +import iped.engine.config.CategoryConfig; +import iped.engine.config.ConfigurationManager; +import iped.engine.data.Category; + +public class CategorySetConfigPanel extends ConfigurablePanel { + private JTree categoryTree; + Configurable> ceConfig; + private JScrollPane treeScrollPanel; + private ConfigCheckBoxTreeCellRenderer cellRenderer; + Set tempCatNames; + + protected CategorySetConfigPanel(Configurable> configurable, MainFrame mainFrame) { + super(configurable, mainFrame); + ceConfig = configurable; + tempCatNames = new HashSet(); + Set configCatNames = ceConfig.getConfiguration(); + for (Iterator iterator = configCatNames.iterator(); iterator.hasNext();) { + tempCatNames.add(iterator.next()); + } + } + + @Override + public void createConfigurableGUI() { + CategoryConfig cc = ConfigurationManager.get().findObject(CategoryConfig.class); + + categoryTree = new JTree(new CategoryMimeTreeModel(cc.getRoot())); + cellRenderer = new ConfigCheckBoxTreeCellRenderer(categoryTree, new Predicate() { + @Override + public boolean apply(Object input) { + return tempCatNames.contains(((Category) input).getName()); + } + }); + cellRenderer.getCheckbox().addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + Category selectedCategory = ((Category) categoryTree.getLastSelectedPathComponent()); + if (selectedCategory != null) { + Set cats = tempCatNames; + String selectedCategoryName = selectedCategory.getName(); + if (cats.contains(selectedCategoryName)) { + cats.remove(selectedCategoryName); + } else { + cats.add(selectedCategoryName); + } + changed = true; + } + } + }); + categoryTree.setCellRenderer(cellRenderer); + + treeScrollPanel = new JScrollPane(); + treeScrollPanel.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + treeScrollPanel.setViewportView(categoryTree); + treeScrollPanel.setAutoscrolls(true); + + this.setLayout(new BorderLayout()); + this.add(treeScrollPanel, BorderLayout.CENTER); + } + + @Override + public void applyChanges() throws ConfigurableValidationException { + ceConfig.setConfiguration(tempCatNames); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/CheckboxListCellRenderer.java b/iped-app/src/main/java/iped/app/home/configurables/CheckboxListCellRenderer.java new file mode 100644 index 0000000000..e40ae651bb --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/CheckboxListCellRenderer.java @@ -0,0 +1,51 @@ +package iped.app.home.configurables; + +import java.awt.BorderLayout; +import java.awt.Component; + +import javax.swing.JCheckBox; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.ListCellRenderer; + +import com.google.common.base.Predicate; + +public class CheckboxListCellRenderer extends JPanel implements ListCellRenderer { + JCheckBox enabledCheckBox = new JCheckBox(); + Predicate isEnabled; + int maxStringWidth = 0; + boolean indexedPredicate = false; + + public CheckboxListCellRenderer(Predicate isEnabled) { + this.setLayout(new BorderLayout()); + this.isEnabled = isEnabled; + add(enabledCheckBox, BorderLayout.CENTER); + } + + public CheckboxListCellRenderer(Predicate isEnabled, boolean indexedPredicate) { + this(isEnabled); + this.indexedPredicate = indexedPredicate; + } + + @Override + public Component getListCellRendererComponent(JList list, E value, int index, boolean isSelected, boolean cellHasFocus) { + if (indexedPredicate) { + enabledCheckBox.setSelected(isEnabled.apply(index)); + } else { + enabledCheckBox.setSelected(isEnabled.apply(value)); + } + enabledCheckBox.setText(value.toString()); + + this.add(enabledCheckBox, BorderLayout.CENTER); + + return this; + } + + public int getMaxStringWidth() { + if (maxStringWidth < enabledCheckBox.getWidth()) { + maxStringWidth = enabledCheckBox.getWidth(); + } + return maxStringWidth; + } + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/ConfigurablePanel.java b/iped-app/src/main/java/iped/app/home/configurables/ConfigurablePanel.java new file mode 100644 index 0000000000..9e844762c6 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/ConfigurablePanel.java @@ -0,0 +1,111 @@ +package iped.app.home.configurables; + +import java.awt.Component; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyVetoException; +import java.beans.VetoableChangeListener; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.swing.SpringLayout; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +import iped.app.home.DefaultPanel; +import iped.app.home.MainFrame; +import iped.app.home.configurables.api.ConfigurableValidationException; +import iped.app.home.configurables.api.IConfigurablePanel; +import iped.configuration.Configurable; + +/** + * @created 10/11/2022 + * @project IPED + * @author Patrick Dalla Bernardina + */ + +public abstract class ConfigurablePanel extends DefaultPanel implements DocumentListener, IConfigurablePanel, VetoableChangeListener { + protected Configurable configurable; + protected SpringLayout layout; + protected boolean changed = false; + + List changeListeners = new ArrayList(); + + protected ConfigurablePanel(Configurable configurable, MainFrame mainFrame) { + super(mainFrame); + this.configurable = configurable; + } + + /** + * Creates the UI objects of the panel. Every editable UI must install "this" + * object as a DocumentListener to keep track of changes + */ + abstract public void createConfigurableGUI(); + + /** + * Applies the changes made on UI objects to the underlying configurable object + */ + abstract public void applyChanges() throws ConfigurableValidationException; + + @Override + protected void createAndShowGUI() { + layout = new SpringLayout(); + + this.setLayout(layout); + } + + @Override + public void insertUpdate(DocumentEvent e) { + changedUpdate(e); + } + + @Override + public void removeUpdate(DocumentEvent e) { + changedUpdate(e); + } + + @Override + public void changedUpdate(DocumentEvent e) { + changed = true; + fireChangeListener(new ChangeEvent(e.getDocument())); + } + + public boolean hasChanged() { + return changed; + } + + public Configurable getConfigurable() { + return configurable; + } + + public void setConfigurable(Configurable configurable) { + this.configurable = configurable; + } + + public void fireChangeListener(ChangeEvent e) { + for (Iterator iterator = changeListeners.iterator(); iterator.hasNext();) { + ChangeListener changeListener = (ChangeListener) iterator.next(); + changeListener.stateChanged(e); + } + } + + public void addChangeListener(ChangeListener changeListener) { + changeListeners.add(changeListener); + } + + public void removeChangeListener(ChangeListener changeListener) { + changeListeners.remove(changeListener); + } + + @Override + public Component getPanel() { + return this; + } + + public void vetoableChange(PropertyChangeEvent e) throws PropertyVetoException { + changed = true; + fireChangeListener(new ChangeEvent(e.getSource())); + } +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/ConfigurablePanelFactory.java b/iped-app/src/main/java/iped/app/home/configurables/ConfigurablePanelFactory.java new file mode 100644 index 0000000000..d004c47a9d --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/ConfigurablePanelFactory.java @@ -0,0 +1,123 @@ +package iped.app.home.configurables; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import iped.app.home.MainFrame; +import iped.app.home.configurables.api.IConfigurablePanel; +import iped.app.home.configurables.api.IConfigurablePanelFactory; +import iped.app.home.configurables.bean.BeanConfigurablePanel; +import iped.configuration.Configurable; +import iped.engine.config.CategoryConfig; +import iped.engine.config.CategoryToExpandConfig; +import iped.engine.config.ExternalParsersConfig; +import iped.engine.config.MakePreviewConfig; +import iped.engine.config.ParsersConfig; +import iped.engine.config.RegexTaskConfig; +import iped.engine.task.AbstractTask; +import iped.engine.task.ExportFileTask; +import iped.engine.task.carver.XMLCarverConfiguration; +import iped.utils.UTF8Properties; + +public class ConfigurablePanelFactory implements IConfigurablePanelFactory { + + private static IConfigurablePanelFactory singleton; + + /** + * Hard coded factory to instantiate IConfigurablePanel suitable to the + * configurable object. + * + * @param configurable + * - the configurable object that the created ConfigurablePanel will + * handle. + * @param mainFrame + * - the main frame of the panel. + */ + @Override + public IConfigurablePanel createConfigurablePanel(AbstractTask task, Configurable configurable, MainFrame mainFrame) { + Object config = configurable.getConfiguration(); + ConfigurablePanel result = null; + + if (config instanceof UTF8Properties) { + result = new UTF8PropertiesConfigurablePanel((Configurable) configurable, mainFrame); + } else if (configurable instanceof ParsersConfig) { + result = new ParsersConfigurablePanel((ParsersConfig) configurable, mainFrame); + } else if (configurable instanceof ExternalParsersConfig) { + result = new ParsersConfigurablePanel((ExternalParsersConfig) configurable, mainFrame); + } else if (configurable instanceof CategoryConfig) { + result = new SetCategoryConfigurablePanel((CategoryConfig) configurable, mainFrame); + } else if (config instanceof String) { + /* try to see if it is a json object */ + boolean isJson = false; + String strConfig = (String) config; + if (strConfig.trim().startsWith("{")) { + JSONParser parser = new JSONParser(); + try { + parser.parse(strConfig); + isJson = true; + } catch (ParseException e) { + } + } + + if (isJson) { + result = new JSONConfigurablePanel((Configurable) configurable, mainFrame); + } else { + /* try to see if it is a xml object */ + try { + if (strConfig.trim().startsWith(") configurable, mainFrame); + } + } finally { + if (result == null) { + result = new TextConfigurablePanel((Configurable) configurable, mainFrame); + } + } + } + } else if (configurable instanceof CategoryToExpandConfig) { + result = new CategorySetConfigPanel((CategoryToExpandConfig) configurable, mainFrame); + } else if (configurable instanceof MakePreviewConfig) { + result = new MakePreviewConfigurablePanel((MakePreviewConfig) configurable, mainFrame); + } else if (config instanceof XMLCarverConfiguration) { + result = new XMLCarverConfigurablePanel((Configurable) configurable, mainFrame); + } else if (configurable.getClass().equals(RegexTaskConfig.class)) { + result = new RegexConfigurablePanel((Configurable) configurable, mainFrame); + } else if (config instanceof Collection) { + if (task instanceof ExportFileTask && config instanceof Set) { + result = new CategorySetConfigPanel((Configurable>) configurable, mainFrame); + } else { + Type type; + try { + type = configurable.getClass().getMethod("getConfiguration").getGenericReturnType(); + if (type instanceof ParameterizedType) { + ParameterizedType ptype = (ParameterizedType) type; + Type[] typeArguments = ptype.getActualTypeArguments(); + if (typeArguments[0].getTypeName().equals(String.class.getCanonicalName())) { + result = new StringSetConfigurablePanel((Configurable>) configurable, mainFrame); + } + } + } catch (NoSuchMethodException | SecurityException e) { + e.printStackTrace(); + } + } + } + if (result == null) { + result = new BeanConfigurablePanel((Configurable) configurable, mainFrame); + } + + return result; + } + + public static IConfigurablePanelFactory getInstance() { + if (singleton == null) { + singleton = new ConfigurablePanelFactory(); + } + return singleton; + } + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/EnableTaskConfigurablePanel.java b/iped-app/src/main/java/iped/app/home/configurables/EnableTaskConfigurablePanel.java new file mode 100644 index 0000000000..d06a429ff1 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/EnableTaskConfigurablePanel.java @@ -0,0 +1,63 @@ +package iped.app.home.configurables; + +import java.util.Iterator; +import java.util.Map.Entry; +import java.util.Set; + +import javax.swing.JLabel; +import javax.swing.JTextField; +import javax.swing.SpringLayout; + +import iped.app.home.MainFrame; +import iped.engine.config.EnableTaskProperty; +import iped.utils.UTF8Properties; + +public class EnableTaskConfigurablePanel extends ConfigurablePanel { + + private JTextField textField; + + protected EnableTaskConfigurablePanel(EnableTaskProperty configurable, MainFrame mainFrame) { + super(configurable, mainFrame); + } + + @Override + public void createConfigurableGUI() { + UTF8Properties config = (UTF8Properties) configurable.getConfiguration(); + if (config != null) { + Set> es = config.entrySet(); + for (Iterator> iterator = es.iterator(); iterator.hasNext();) { + Entry e = iterator.next(); + if (e.getKey().equals(((EnableTaskProperty) configurable).getPropertyName())) { + JLabel label = new JLabel(e.getKey() + ":"); + layout.putConstraint(SpringLayout.NORTH, label, 15, SpringLayout.NORTH, this); + this.add(label); + Object o = e.getValue(); + textField = new JTextField(); + if (o != null) { + textField.setText(o.toString()); + } + textField.getDocument().addDocumentListener(this); + layout.putConstraint(SpringLayout.VERTICAL_CENTER, textField, 0, SpringLayout.VERTICAL_CENTER, label); + layout.putConstraint(SpringLayout.WEST, textField, 5, SpringLayout.EAST, label); + this.add(textField); + } + } + } + + } + + @Override + public void applyChanges() { + UTF8Properties config = (UTF8Properties) configurable.getConfiguration(); + if (config != null) { + Set> es = config.entrySet(); + for (Iterator> iterator = es.iterator(); iterator.hasNext();) { + Entry e = iterator.next(); + if (e.getKey().equals(((EnableTaskProperty) configurable).getPropertyName())) { + config.setProperty(e.getKey().toString(), textField.getText()); + } + } + } + } + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/JSONConfigurablePanel.java b/iped-app/src/main/java/iped/app/home/configurables/JSONConfigurablePanel.java new file mode 100644 index 0000000000..050a4957be --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/JSONConfigurablePanel.java @@ -0,0 +1,43 @@ +package iped.app.home.configurables; + +import org.fife.ui.rsyntaxtextarea.SyntaxConstants; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import iped.app.home.MainFrame; +import iped.app.home.configurables.api.ConfigurableValidationException; +import iped.configuration.Configurable; + +public class JSONConfigurablePanel extends TextConfigurablePanel { + + private String config; + + protected JSONConfigurablePanel(Configurable configurable, MainFrame mainFrame) { + super(configurable, mainFrame); + config = configurable.getConfiguration(); + } + + @Override + public void createConfigurableGUI() { + super.createConfigurableGUI(); + textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON_WITH_COMMENTS); + // textArea.setCodeFoldingEnabled(true); + // textArea.setEditorKitForContentType("text/xml", new JSONEditorKit()); + // textArea.setContentType("text/xml"); + textArea.getDocument().removeDocumentListener(this); + textArea.setText(config); + textArea.getDocument().addDocumentListener(this); + + } + + @Override + public void applyChanges() throws ConfigurableValidationException { + try { + JSONParser parser = new JSONParser(); + parser.parse(textArea.getText()); + } catch (ParseException e) { + throw new ConfigurableValidationException("Erro de sintaxe JSON.", e); + } + } + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/MakePreviewConfigurablePanel.java b/iped-app/src/main/java/iped/app/home/configurables/MakePreviewConfigurablePanel.java new file mode 100644 index 0000000000..a363edd1bd --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/MakePreviewConfigurablePanel.java @@ -0,0 +1,213 @@ +package iped.app.home.configurables; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.TooManyListenersException; + +import javax.swing.DropMode; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.ScrollPaneConstants; + +import iped.app.home.MainFrame; +import iped.app.home.configurables.api.ConfigurableValidationException; +import iped.app.home.configurables.uicomponents.IPEDMimeSearchList; +import iped.app.home.configurables.uicomponents.MimeListTransferHandler; +import iped.app.ui.controls.textarea.RegexTextPane; +import iped.engine.config.MakePreviewConfig; +import iped.engine.localization.Messages; + +public class MakePreviewConfigurablePanel extends ConfigurablePanel { + MakePreviewConfig previewConfig; + protected RegexTextPane textAreaSupportedMimes; + protected RegexTextPane textAreaSupportedMimesWithLinks; + private JSplitPane splitPane; + private DropTarget dtMime; + private JList listSupportedMimes; + private JList listSupportedMimesWithLinks; + private DropTargetAdapter dtlistener; + private DropTarget dtSupportedMimesWithLinks; + private DropTarget dtSupportedMimes; + private JList dragSourceList; + private MouseAdapter listMA; + + List supportedMimes = new ArrayList(); + List supportedMimesWithLinks = new ArrayList(); + + protected MakePreviewConfigurablePanel(MakePreviewConfig configurable, MainFrame mainFrame) { + super(configurable, mainFrame); + this.previewConfig = configurable; + supportedMimes.addAll(this.previewConfig.getSupportedMimes()); + supportedMimesWithLinks.addAll(this.previewConfig.getSupportedMimesWithLinks()); + } + + @Override + public void createConfigurableGUI() { + this.setLayout(new BorderLayout()); + + splitPane = new JSplitPane(); + splitPane.setDividerSize(4); + + this.add(splitPane, BorderLayout.CENTER); + + IPEDMimeSearchList slmime = new IPEDMimeSearchList(); + slmime.setBackground(this.getBackground()); + splitPane.setLeftComponent(slmime); + slmime.setTransferHandler(new MimeListTransferHandler(slmime.getListComponent())); + slmime.setDragEnabled(true); + slmime.setDropMode(DropMode.ON); + dtlistener = new DropTargetAdapter() { + @Override + public void drop(DropTargetDropEvent dtde) { + if (dtde.getDropTargetContext().getComponent() == slmime.getListComponent()) { + if (dragSourceList == listSupportedMimes) { + try { + Object[] o = (Object[]) dtde.getTransferable().getTransferData(DataFlavor.stringFlavor); + for (int i = 0; i < o.length; i++) { + supportedMimes.remove((String) o[i]); + } + JList supportList = new JList(supportedMimes.toArray(new String[0])); + listSupportedMimes.setModel(supportList.getModel()); + changed = true; + } catch (UnsupportedFlavorException | IOException e) { + e.printStackTrace(); + } + } + if (dragSourceList == listSupportedMimesWithLinks) { + try { + Object[] o = (Object[]) dtde.getTransferable().getTransferData(DataFlavor.stringFlavor); + for (int i = 0; i < o.length; i++) { + supportedMimesWithLinks.remove((String) o[i]); + } + JList supportList = new JList(supportedMimesWithLinks.toArray(new String[0])); + listSupportedMimesWithLinks.setModel(supportList.getModel()); + changed = true; + } catch (UnsupportedFlavorException | IOException e) { + e.printStackTrace(); + } + } + } + if (dtde.getDropTargetContext().getComponent() == listSupportedMimes) { + try { + Object[] o = (Object[]) dtde.getTransferable().getTransferData(DataFlavor.stringFlavor); + for (int i = 0; i < o.length; i++) { + supportedMimes.add((String) o[i]); + } + JList supportList = new JList(supportedMimes.toArray(new String[0])); + listSupportedMimes.setModel(supportList.getModel()); + changed = true; + } catch (UnsupportedFlavorException | IOException e) { + e.printStackTrace(); + } + } + if (dtde.getDropTargetContext().getComponent() == listSupportedMimesWithLinks) { + try { + Object[] o = (Object[]) dtde.getTransferable().getTransferData(DataFlavor.stringFlavor); + for (int i = 0; i < o.length; i++) { + supportedMimesWithLinks.add((String) o[i]); + } + JList supportList = new JList(supportedMimesWithLinks.toArray(new String[0])); + listSupportedMimesWithLinks.setModel(supportList.getModel()); + changed = true; + } catch (UnsupportedFlavorException | IOException e) { + e.printStackTrace(); + } + } + } + + @Override + public void dragEnter(DropTargetDragEvent dtde) { + Component srcComponent = ((DropTarget) dtde.getSource()).getComponent(); + if (srcComponent == listSupportedMimes || srcComponent == listSupportedMimesWithLinks || srcComponent == slmime.getListComponent()) { + dtde.acceptDrag(DnDConstants.ACTION_MOVE); + } else { + dtde.rejectDrag(); + } + } + }; + dtMime = new DropTarget(); + try { + dtMime.addDropTargetListener(dtlistener); + } catch (TooManyListenersException e) { + e.printStackTrace(); + } + slmime.setDropTarget(dtMime); + + JSplitPane rightPanel = new JSplitPane(); + rightPanel.setDividerSize(4); + rightPanel.setResizeWeight(.8); + rightPanel.setOrientation(JSplitPane.VERTICAL_SPLIT); + splitPane.setRightComponent(rightPanel); + + listMA = new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + dragSourceList = (JList) e.getSource(); + } + }; + + listSupportedMimes = new JList(supportedMimes.toArray(new String[0])); + JPanel textPanel = new JPanel(new BorderLayout()); + textPanel.setBackground(this.getBackground()); + textPanel.add(new JLabel(Messages.getString(configurable.getClass().getName() + ".supportedMimeTypes")), BorderLayout.NORTH); + JScrollPane sp = new JScrollPane(listSupportedMimes); + sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + textPanel.add(sp, BorderLayout.CENTER); + rightPanel.setTopComponent(textPanel); + listSupportedMimes.setDragEnabled(true); + listSupportedMimes.setTransferHandler(new MimeListTransferHandler(listSupportedMimes)); + dtSupportedMimes = new DropTarget(); + try { + dtSupportedMimes.addDropTargetListener(dtlistener); + } catch (TooManyListenersException e) { + e.printStackTrace(); + } + listSupportedMimes.setDropTarget(dtSupportedMimes); + listSupportedMimes.addMouseListener(listMA); + + listSupportedMimesWithLinks = new JList(supportedMimesWithLinks.toArray(new String[0])); + listSupportedMimesWithLinks.setAutoscrolls(true); + textPanel = new JPanel(new BorderLayout()); + textPanel.setBackground(this.getBackground()); + textPanel.add(new JLabel(Messages.getString(configurable.getClass().getName() + ".supportedMimeTypesWithLinks")), BorderLayout.NORTH); + sp = new JScrollPane(listSupportedMimesWithLinks); + sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + textPanel.add(sp, BorderLayout.CENTER); + rightPanel.setBottomComponent(textPanel); + listSupportedMimesWithLinks.setDragEnabled(true); + listSupportedMimesWithLinks.setTransferHandler(new MimeListTransferHandler(listSupportedMimesWithLinks)); + dtSupportedMimesWithLinks = new DropTarget(); + try { + dtSupportedMimesWithLinks.addDropTargetListener(dtlistener); + } catch (TooManyListenersException e) { + e.printStackTrace(); + } + listSupportedMimesWithLinks.setDropTarget(dtSupportedMimesWithLinks); + listSupportedMimesWithLinks.addMouseListener(listMA); + } + + @Override + public void applyChanges() throws ConfigurableValidationException { + if (changed) { + previewConfig.getSupportedMimes().clear(); + previewConfig.getSupportedMimes().addAll(supportedMimes); + previewConfig.getSupportedMimesWithLinks().clear(); + previewConfig.getSupportedMimesWithLinks().addAll(supportedMimesWithLinks); + } + } +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/ParserTreeCellEditor.java b/iped-app/src/main/java/iped/app/home/configurables/ParserTreeCellEditor.java new file mode 100644 index 0000000000..efe1a2b6a1 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/ParserTreeCellEditor.java @@ -0,0 +1,174 @@ +package iped.app.home.configurables; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; +import java.lang.reflect.Field; +import java.util.EventObject; + +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.JTree; +import javax.swing.event.CellEditorListener; +import javax.swing.tree.TreePath; + +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import iped.app.home.configurables.ParsersTreeModel.ParserElementName; + +public class ParserTreeCellEditor extends JPanel implements javax.swing.tree.TreeCellEditor { + + private JComboBox booleanCombo; + private JTextField textEditor; + private JLabel label; + TreePath tp; + private Field f; + + public ParserTreeCellEditor() { + booleanCombo = new JComboBox(); + booleanCombo.addItem(true); + booleanCombo.addItem(false); + textEditor = new JTextField(); + label = new JLabel(); + + textEditor.addKeyListener(new KeyListener() { + @Override + public void keyTyped(KeyEvent e) { + } + + @Override + public void keyReleased(KeyEvent e) { + } + + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == e.VK_ENTER) { + JTree tree = (JTree) e.getComponent().getParent().getParent(); + tree.stopEditing(); + } + if (e.getKeyCode() == e.VK_ESCAPE) { + JTree tree = (JTree) e.getComponent().getParent().getParent(); + tree.cancelEditing(); + } + } + }); + } + + @Override + public Object getCellEditorValue() { + return null; + } + + @Override + public boolean isCellEditable(EventObject anEvent) { + if (anEvent instanceof MouseEvent) { + JTree tree = (JTree) anEvent.getSource(); + MouseEvent me = (MouseEvent) anEvent; + + tp = tree.getPathForLocation(me.getX(), me.getY()); + + if (tp != null) { + Object value = tp.getLastPathComponent(); + return value instanceof Field; + } else { + return false; + } + } + return false; + } + + @Override + public boolean shouldSelectCell(EventObject anEvent) { + return false; + } + + @Override + public boolean stopCellEditing() { + Element element = ((ParserElementName) tp.getParentPath().getLastPathComponent()).getElement(); + NodeList nlParamss = element.getElementsByTagName("params"); + if (nlParamss != null) { + Element el = (Element) nlParamss.item(0); + NodeList nlParams = el.getElementsByTagName("param"); + for (int i = 0; i < nlParams.getLength(); i++) { + Element param = (Element) nlParams.item(i); + if (param.getAttribute("name").equals(f.getName())) { + param.getFirstChild().setNodeValue(textEditor.getText()); + break; + } + } + } + return true; + } + + @Override + public void cancelCellEditing() { + + } + + @Override + public void addCellEditorListener(CellEditorListener l) { + // TODO Auto-generated method stub + + } + + @Override + public void removeCellEditorListener(CellEditorListener l) { + // TODO Auto-generated method stub + + } + + @Override + public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) { + if (value instanceof Field) { + f = (Field) value; + + Object tpValue = tree.getPathForRow(row).getParentPath().getLastPathComponent(); + if (!(tpValue instanceof ParserElementName)) + return null; + + this.removeAll(); + this.setLayout(new FlowLayout()); + + label.setText(f.getName() + ":"); + this.add(label); + + String fieldValue = null; + Element element = ((ParserElementName) tpValue).getElement(); + NodeList nlParamss = element.getElementsByTagName("params"); + if (nlParamss != null) { + Element el = (Element) nlParamss.item(0); + NodeList nlParams = el.getElementsByTagName("param"); + for (int i = 0; i < nlParams.getLength(); i++) { + Element param = (Element) nlParams.item(i); + if (param.getAttribute("name").equals(f.getName())) { + fieldValue = param.getFirstChild().getNodeValue(); + break; + } + } + } + + if (f.getType() == Boolean.class) { + this.removeAll(); + this.add(booleanCombo); + } else { + textEditor.setPreferredSize(new Dimension(200, 32)); + if (fieldValue != null) { + textEditor.setText(fieldValue); + } else { + textEditor.setText(""); + } + this.add(textEditor); + } + + return this; + } + return null; + } + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/ParsersConfigurablePanel.java b/iped-app/src/main/java/iped/app/home/configurables/ParsersConfigurablePanel.java new file mode 100644 index 0000000000..a19ad4f650 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/ParsersConfigurablePanel.java @@ -0,0 +1,479 @@ +package iped.app.home.configurables; + +import java.awt.Color; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyVetoException; +import java.beans.VetoableChangeListener; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; +import java.util.SortedSet; + +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.JTextField; +import javax.swing.JTree; +import javax.swing.SpringLayout; +import javax.swing.SwingUtilities; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; + +import org.apache.tika.mime.MediaType; +import org.apache.tika.mime.MediaTypeRegistry; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.fife.ui.autocomplete.AutoCompletion; +import org.fife.ui.autocomplete.Completion; +import org.fife.ui.autocomplete.DefaultCompletionProvider; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.SyntaxConstants; +import org.fife.ui.rtextarea.RTextScrollPane; +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import com.google.common.base.Predicate; + +import iped.app.home.MainFrame; +import iped.app.home.configurables.ParsersTreeModel.ParserElementName; +import iped.app.home.configurables.api.ConfigurableValidationException; +import iped.app.home.configurables.autocompletion.CharsetCompletionProvider; +import iped.app.home.configurables.autocompletion.MimetypeAutoCompletionProvider; +import iped.app.home.configurables.popups.ExternalParserPopup; +import iped.app.ui.CategoryMimeTreeModel; +import iped.app.ui.Messages; +import iped.app.ui.controls.CheckBoxTreeCellRenderer; +import iped.app.ui.controls.ConfigCheckBoxTreeCellRenderer; +import iped.configuration.Configurable; +import iped.engine.config.CategoryConfig; +import iped.engine.config.ConfigurationManager; +import iped.engine.config.ParsersConfig; +import iped.engine.data.Category; + +public class ParsersConfigurablePanel extends AdvancedTextConfigurablePanel { + protected Configurable parsersConfig; + private JScrollPane parserListPanel; + private JTree parsersTree; + private JTree categoryTree; + private JSplitPane splitPane; + private CategoryConfig cc; + private ParsersTreeModel parsersModel; + private ConfigCheckBoxTreeCellRenderer cellRenderer; + private ParserTreeCellEditor cellEditor; + private JScrollPane categoryPanel; + private CategoryMimeTreeModel categoryTreeModel; + private Category categoryRoot; + private ExternalParserPopup externalParserPopup; + private MouseAdapter popupMouseAdapter; + private JPanel createExternalParserPanel; + private SpringLayout panelLayout; + private int max; + private JLabel largestLabel; + private ArrayList comps = new ArrayList(); + private Component lastLabel; + private JTextField txName; + private JTextField txCheckCommand; + private JTextField txCheckErroCodes; + private JTextField txCommand; + private RSyntaxTextArea txMimetypes; + private RSyntaxTextArea txCharset; + private JTextField txLines; + private DefaultCompletionProvider mimeCompletionProvider; + private MimetypeAutoCompletionProvider mtac; + private CharsetCompletionProvider csac; + private VetoableChangeListener externalParserEditingVeto; + + protected ParsersConfigurablePanel(Configurable configurable, MainFrame mainFrame) { + super(configurable, mainFrame); + this.parsersConfig = configurable; + cc = ConfigurationManager.get().findObject(CategoryConfig.class); + categoryRoot = cc.getRoot().clone(); + } + + @Override + public void createConfigurableGUI() { + super.createConfigurableGUI(); + + textArea.getDocument().removeDocumentListener(this); + textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_XML); + textArea.setText(parsersConfig.getConfiguration()); + textArea.getDocument().addDocumentListener(this); + + if (parsersModel.isExternalParsers()) { + createNewExternalParserPanel(); + } + } + + @Override + protected Component getBasicPane() { + if (splitPane == null) { + createParserListPanel(); + } + return splitPane; + } + + public void installField(String textLabel, Component component) { + JLabel label = new JLabel(textLabel); + if (lastLabel != null) { + panelLayout.putConstraint(SpringLayout.NORTH, label, 15, SpringLayout.SOUTH, lastLabel); + } else { + panelLayout.putConstraint(SpringLayout.NORTH, label, 15, SpringLayout.NORTH, createExternalParserPanel); + } + int width = label.getText().length(); + if (max < width) { + max = width; + largestLabel = label; + } + comps.add(label); + Component uiField; + if (component instanceof JTextField) { + panelLayout.putConstraint(SpringLayout.VERTICAL_CENTER, component, 0, SpringLayout.VERTICAL_CENTER, label); + } else { + panelLayout.putConstraint(SpringLayout.NORTH, component, 0, SpringLayout.NORTH, label); + } + comps.add(component); + lastLabel = component; + } + + public void createNewExternalParserPanel() { + createExternalParserPanel = new JPanel(); + createExternalParserPanel.setBackground(Color.white); + JLabel lastLabel = null; + panelLayout = new SpringLayout(); + createExternalParserPanel.setLayout(panelLayout); + + txName = new JTextField(""); + installField("Parser name:", txName); + txCheckCommand = new JTextField(); + installField("Check command:", txCheckCommand); + + txCheckErroCodes = new JTextField("1"); + installField("Check error codes:", txCheckErroCodes); + + txCommand = new JTextField("${INPUT}"); + installField("Command:", txCommand); + + txMimetypes = new RSyntaxTextArea(5, 80); + txMimetypes.setHighlightCurrentLine(false); + mtac = new MimetypeAutoCompletionProvider(); + AutoCompletion ac = new AutoCompletion(mtac); + ac.install(txMimetypes); + installField("Mime-types:", new RTextScrollPane(txMimetypes)); + + txCharset = new RSyntaxTextArea(); + txCharset.setHighlightCurrentLine(false); + RTextScrollPane charsetPanel = new RTextScrollPane(txCharset); + charsetPanel.setLineNumbersEnabled(false); + charsetPanel.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); + installField("Charset:", charsetPanel); + csac = new CharsetCompletionProvider(); + ac = new AutoCompletion(csac); + ac.install(txCharset); + + txLines = new JTextField("0"); + installField("First lines to ignore:", txLines); + + for (Iterator iterator = comps.iterator(); iterator.hasNext();) { + Component component = (Component) iterator.next(); + if (component != largestLabel) { + if (component instanceof JLabel) { + panelLayout.putConstraint(SpringLayout.EAST, component, 0, SpringLayout.EAST, largestLabel); + } else { + panelLayout.putConstraint(SpringLayout.WEST, component, 5, SpringLayout.EAST, largestLabel); + panelLayout.putConstraint(SpringLayout.EAST, component, -15, SpringLayout.EAST, createExternalParserPanel); + } + } + createExternalParserPanel.add(component); + } + ParsersConfigurablePanel self = this; + + JButton cancelExternalParserBtn = new JButton(Messages.get("Home.Cancel")); + cancelExternalParserBtn.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + ((VetoableSingleSelectionModel) tabbedPane.getModel()).removeVetoableChangeListener(externalParserEditingVeto); + tabbedPane.setSelectedIndex(0); + tabbedPane.removeTabAt(2); + } + }); + JButton createExternalParserBtn = new JButton(Messages.get("iped.app.home.configurables.ParsersConfigurablePanel.CreateExternalParser")); + createExternalParserBtn.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (txName.getText().trim().equals("")) { + JOptionPane.showMessageDialog(createExternalParserPanel, Messages.get("iped.app.home.configurables.ParsersConfigurablePanel.EmptyNameError")); + return; + } + if (txCommand.getText().trim().equals("${INPUT}")) { + JOptionPane.showMessageDialog(createExternalParserPanel, Messages.get("iped.app.home.configurables.ParsersConfigurablePanel.EmptyCommandError")); + return; + } + if (txMimetypes.getText().trim().equals("")) { + JOptionPane.showMessageDialog(createExternalParserPanel, Messages.get("iped.app.home.configurables.ParsersConfigurablePanel.EmptyMimeTypeError")); + } + SortedSet mts = MediaTypeRegistry.getDefaultRegistry().getTypes(); + String[] mimetypes = txMimetypes.getText().split("\n"); + for (int i = 0; i < mimetypes.length; i++) { + String[] mimeparts = mimetypes[i].trim().split("/"); + if (mimeparts.length < 2) { + JOptionPane.showMessageDialog(createExternalParserPanel, Messages.get("iped.app.home.configurables.ParsersConfigurablePanel.InvalidMimeTypeError") + ": " + mimetypes[i] + "."); + } + MediaType mt = new MediaType(mimeparts[0], mimeparts[1]); + if (!mtac.containsKeyword(mt.toString())) { + JOptionPane.showMessageDialog(createExternalParserPanel, Messages.get("iped.app.home.configurables.ParsersConfigurablePanel.UnregisteredMimeTypeError") + ": " + mimetypes[i] + "."); + return; + } + } + if (txCharset.getText().trim().equals("")) { + JOptionPane.showMessageDialog(createExternalParserPanel, Messages.get("iped.app.home.configurables.ParsersConfigurablePanel.EmptyCharsetError")); + return; + } + + try { + Integer.parseInt(txLines.getText().trim()); + } catch (NumberFormatException ex) { + JOptionPane.showMessageDialog(createExternalParserPanel, Messages.get("iped.app.home.configurables.ParsersConfigurablePanel.InvalidFirstLinesToSkipError")); + } + + List cs = csac.getCompletionByInputText(txCharset.getText().trim()); + if (cs == null || cs.size() != 1) { + JOptionPane.showMessageDialog(createExternalParserPanel, Messages.get("iped.app.home.configurables.ParsersConfigurablePanel.InvalidCharsetError")); + return; + } + createExternalParserElement(); + ((VetoableSingleSelectionModel) tabbedPane.getModel()).removeVetoableChangeListener(externalParserEditingVeto); + tabbedPane.setSelectedIndex(0); + tabbedPane.remove(createExternalParserPanel); + self.changed = true; + + } + }); + JPanel btnPanel = new JPanel(); + btnPanel.setBackground(this.getBackground()); + btnPanel.add(createExternalParserBtn); + btnPanel.add(cancelExternalParserBtn); + panelLayout.putConstraint(SpringLayout.SOUTH, btnPanel, -30, SpringLayout.SOUTH, createExternalParserPanel); + panelLayout.putConstraint(SpringLayout.HORIZONTAL_CENTER, btnPanel, 0, SpringLayout.HORIZONTAL_CENTER, createExternalParserPanel); + createExternalParserPanel.add(btnPanel); + } + + public void createExternalParserElement() { + Document doc = parsersModel.getDocument(); + doc.getDocumentElement().getChildNodes().getLength(); + + Element parserEl = doc.createElement("parser"); + Element parserNameEl = (Element) parserEl.appendChild(doc.createElement("name")); + parserNameEl.setTextContent(txName.getText()); + Element checkEl = (Element) parserEl.appendChild(doc.createElement("check")); + checkEl.appendChild(doc.createElement("command")).setTextContent(txCheckCommand.getText()); + ; + checkEl.appendChild(doc.createElement("error-codes")).setTextContent(txCheckErroCodes.getText()); + parserEl.appendChild(doc.createElement("command")).setTextContent(txCommand.getText()); + parserEl.appendChild(doc.createElement("output-charset")).setTextContent(txCharset.getText()); + parserEl.appendChild(doc.createElement("firstLinesToIgnore")).setTextContent(txLines.getText()); + String[] mimetypes = txMimetypes.getText().split("\n"); + Element mimeTypesEl = (Element) parserEl.appendChild(doc.createElement("mime-types")); + for (int i = 0; i < mimetypes.length; i++) { + mimeTypesEl.appendChild(doc.createElement("mime")).setTextContent(mimetypes[i]); + } + doc.getDocumentElement().appendChild(parserEl); + + refreshParsersModel(); + } + + public void createParserListPanel() { + parserListPanel = new JScrollPane(); + parsersModel = new ParsersTreeModel(parsersConfig, categoryRoot); + parsersTree = new JTree(parsersModel); + parsersTree.setRootVisible(false); + parsersTree.setShowsRootHandles(true); + parserListPanel.setViewportView(parsersTree); + parserListPanel.setAutoscrolls(true); + parsersTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); + cellRenderer = new ConfigCheckBoxTreeCellRenderer(parsersTree, new Predicate() { + @Override + public boolean apply(Object input) { + boolean result = false; + if (input instanceof ParserElementName) { + Element elem = ((ParserElementName) input).getElement(); + Attr attr = (Attr) elem.getAttributes().getNamedItem(ParsersConfig.PARSER_DISABLED_ATTR); + + if (attr == null) { + result = true; + } + } + return result; + } + }, new Predicate() { + @Override + public boolean apply(@Nullable Object input) { + return input instanceof ParserElementName; + } + }); + cellRenderer.getCheckbox().addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + Object o = parsersTree.getLastSelectedPathComponent(); + if (o != null) { + if (o instanceof ParserElementName) { + Element elem = ((ParserElementName) o).getElement(); + if (elem != null) { + Attr attr = (Attr) elem.getAttributes().getNamedItem(ParsersConfig.PARSER_DISABLED_ATTR); + + if (attr == null) { + elem.setAttribute(ParsersConfig.PARSER_DISABLED_ATTR, "true"); + } else { + elem.removeAttribute(ParsersConfig.PARSER_DISABLED_ATTR); + } + + textArea.setText(parsersModel.getXMLString()); + + try { + // moves the caret to the line of the changed parser declaration + int lineNumber = Integer.parseInt((String) elem.getUserData(PositionalXMLReader.LINE_NUMBER_KEY_NAME)) - 1; + int offset = textArea.getDocument().getDefaultRootElement().getElement(lineNumber).getStartOffset(); + textArea.setCaretPosition(offset); + } catch (Exception ex) { + ex.printStackTrace(); + } + + changed = true; + } + } + } + } + }); + parsersTree.setCellRenderer(cellRenderer); + parsersTree.setEditable(true); + + categoryTreeModel = new CategoryMimeTreeModel(categoryRoot); + categoryTreeModel.setToShowUncategorizable(true); + categoryTreeModel.hideCategories(new java.util.function.Predicate() { + @Override + public boolean test(Category cat) { + if (cat.equals(categoryRoot)) { + return false; + } else { + List parsers = parsersModel.getCategoryMediaTypesNames(cat); + return parsers != null && parsers.size() <= 0; + } + } + }); + categoryTree = new JTree(categoryTreeModel); + categoryTree.setCellRenderer(new CheckBoxTreeCellRenderer(categoryTree, null, new Predicate() { + @Override + public boolean apply(@Nullable Object input) { + return false;// never shows checkbox + } + })); + categoryTree.setRootVisible(false); + categoryTree.setShowsRootHandles(true); + categoryTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); + categoryTree.addTreeSelectionListener(new TreeSelectionListener() { + @Override + public void valueChanged(TreeSelectionEvent e) { + Object cat = e.getNewLeadSelectionPath().getLastPathComponent(); + if (cat == CategoryMimeTreeModel.uncategorizableName) { + parsersModel.setCategory(null); + } + if (cat instanceof Category) { + parsersModel.setCategory((Category) cat); + } + parsersTree.setModel(parsersModel.copy()); + } + }); + categoryTree.expandRow(1); + categoryPanel = new JScrollPane(); + categoryPanel.setViewportView(categoryTree); + categoryPanel.setAutoscrolls(true); + + splitPane = new JSplitPane(); + splitPane.setRightComponent(parserListPanel); + splitPane.setLeftComponent(categoryPanel); + if (parsersModel.isExternalParsers()) { + externalParserPopup = new ExternalParserPopup(this); + popupMouseAdapter = new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (SwingUtilities.isRightMouseButton(e)) { + int row = categoryTree.getClosestRowForLocation(e.getX(), e.getY()); + categoryTree.setLeadSelectionPath(categoryTree.getPathForRow(row)); + if (categoryTree.getLeadSelectionPath().getLastPathComponent() instanceof Category) { + externalParserPopup.show(e.getComponent(), e.getX(), e.getY()); + } + } + } + }; + parsersTree.addMouseListener(popupMouseAdapter); + } + } + + public void refreshParsersModel() { + // update tree model + Enumeration exps = parsersTree.getExpandedDescendants(parsersTree.getPathForRow(0)); + parsersModel = new ParsersTreeModel(parsersConfig, categoryRoot, getDocument()); + parsersTree.setModel(parsersModel); + if (exps != null) { + while (exps.hasMoreElements()) { + TreePath curpath = exps.nextElement(); + parsersTree.expandPath(curpath); + } + } + textArea.getDocument().removeDocumentListener(this); + textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_XML); + textArea.setText(parsersModel.getXMLString()); + textArea.getDocument().addDocumentListener(this); + } + + @Override + public void applyChanges() throws ConfigurableValidationException { + super.applyChanges(); + } + + public JTree getParsersTree() { + return parsersTree; + } + + public Document getDocument() { + return parsersModel.getDocument(); + } + + public void startExternalParserCreation() { + txName.setText(""); + txCheckCommand.setText(""); + txMimetypes.setText(""); + txCommand.setText(""); + txCheckErroCodes.setText("1"); + txCharset.setText(""); + txLines.setText("0"); + + tabbedPane.addTab(Messages.get("iped.app.home.configurables.ParsersConfigurablePanel.NewExternalParserPanel"), createExternalParserPanel); + tabbedPane.setSelectedComponent(createExternalParserPanel); + externalParserEditingVeto = new VetoableChangeListener() { + @Override + public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException { + PropertyVetoException pve = new PropertyVetoException(Messages.get("iped.app.home.configurables.ParsersConfigurablePanel.EditVetoError"), evt); + throw pve; + } + }; + ((VetoableSingleSelectionModel) tabbedPane.getModel()).addVetoableChangeListener(externalParserEditingVeto); + } + + protected String getBasicPaneTitle() { + return Messages.get("Home.configurables.BasicParsersPanelLabel"); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/ParsersTreeModel.java b/iped-app/src/main/java/iped/app/home/configurables/ParsersTreeModel.java new file mode 100644 index 0000000000..3274b9e655 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/ParsersTreeModel.java @@ -0,0 +1,473 @@ +package iped.app.home.configurables; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.nio.charset.Charset; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +import javax.swing.event.TreeModelListener; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreePath; +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.validation.SchemaFactory; + +import org.apache.commons.io.input.BOMInputStream; +import org.apache.tika.mime.MediaType; +import org.apache.tika.parser.Parser; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +import iped.configuration.Configurable; +import iped.engine.config.CategoryConfig; +import iped.engine.config.ConfigurationManager; +import iped.engine.config.ParsersConfig; +import iped.engine.data.Category; +import iped.parsers.misc.MultipleParser; +import iped.utils.XMLUtil; + +public class ParsersTreeModel implements TreeModel { + Configurable configurable; + final static String ROOT = "Parsers"; + final static String MIME_NODE = "myme-types"; + private HashMap> parsersMediaType = new HashMap>(); + private HashSet parsers = new HashSet(); + private HashMap> categoryMediaType = new HashMap>(); + private HashMap> categoryParsers = new HashMap>(); + private HashMap> parserFields = new HashMap>(); + Category category = null; + Document doc; + private CategoryConfig categoryConfig; + + boolean toListParameters = false; + private boolean externalParsers; + private ArrayList categorizableParsers; + private ArrayList uncategorizableParsers; + + private ParsersTreeModel() { + } + + public ParsersTreeModel(Configurable configurable, Category cat, Document doc) { + this.configurable = configurable; + this.doc = doc; + categoryConfig = ConfigurationManager.get().findObject(CategoryConfig.class); + loadModel(cat); + } + + public ParsersTreeModel(Configurable configurable, Category cat) { + this.configurable = configurable; + categoryConfig = ConfigurationManager.get().findObject(CategoryConfig.class); + loadModel(cat); + } + + private void loadModel(Category cat) { + getDocument(); + populateAvailableParsers(); + if (cat != null) { + populatesCategoryMimes(cat); + } + categorizableParsers = updateFilteredParsers(cat); + uncategorizableParsers = new ArrayList(); + for (Iterator iterator = parsers.iterator(); iterator.hasNext();) { + Element el = (Element) iterator.next(); + ParserElementName parserElementName = new ParserElementName(el); + if (!categorizableParsers.contains(parserElementName)) { + uncategorizableParsers.add(parserElementName); + } + } + categoryParsers.put(null, uncategorizableParsers); + category = cat; + if (!externalParsers) { + updateParsersFields(); + } + } + + public ParsersTreeModel(ParsersConfig configurable) { + this(configurable, null); + } + + @Override + public Object getRoot() { + return ROOT; + } + + public ParsersTreeModel copy() { + ParsersTreeModel copy = new ParsersTreeModel(); + copy.configurable = configurable; + copy.parsers = parsers; + copy.parsersMediaType = parsersMediaType; + copy.categoryMediaType = categoryMediaType; + copy.category = category; + copy.doc = doc; + copy.parserFields = this.parserFields; + copy.categoryConfig = categoryConfig; + copy.categoryParsers = categoryParsers; + return copy; + } + + class ParserElementName implements Comparable { + Element el; + + public ParserElementName(Element el) { + this.el = el; + } + + public Element getElement() { + return el; + } + + @Override + public String toString() { + if (externalParsers) { + return ((Element) el.getElementsByTagName("name").item(0)).getTextContent(); + } else { + /* if there is a param named parserName returns its content */ + Element paramsList = (Element) el.getElementsByTagName("params").item(0); + if (paramsList != null) { + NodeList params = paramsList.getElementsByTagName("param"); + Set result = new TreeSet(); + for (int i = 0; i < params.getLength(); i++) { + if (((Element) params.item(i)).getAttribute("name").equals("parserName")) { + return ((Element) params.item(i)).getTextContent(); + } + } + } + + /* else return parser class name */ + String className = el.getAttributes().getNamedItem("class").getNodeValue(); + return className; + } + } + + @Override + public int compareTo(ParserElementName o) { + return o.toString().compareTo(this.toString()); + } + + @Override + public boolean equals(Object obj) { + return (obj instanceof ParserElementName) && ((ParserElementName) obj).el == this.el; + } + } + + public List getCategoryMediaTypesNames(Category category) { + return categoryParsers.get(category); + } + + @Override + public Object getChild(Object parent, int index) { + if (parent == ROOT) { + List filteredParsers = categoryParsers.get(category); + return filteredParsers.get(index); + } else { + if (parent instanceof ParserElementName) { + Element el = ((ParserElementName) parent).getElement(); + Set mimes = parsersMediaType.get(el); + int mimesSize = mimes != null ? mimes.size() : 0; + if (index < mimesSize) { + return mimes.toArray(new MediaType[0])[index]; + } else { + return parserFields.get(el).get(index - mimesSize); + } + + } + } + return null; + } + + @Override + public int getChildCount(Object parent) { + if (parent == ROOT) { + List filteredParsers = categoryParsers.get(category); + return filteredParsers == null ? 0 : filteredParsers.size(); + } else { + if (parent instanceof ParserElementName) { + Element el = ((ParserElementName) parent).getElement(); + Set mimes = parsersMediaType.get(el); + int result = 0; + if (mimes != null) { + result += mimes.size(); + } + if (toListParameters) { + List fs = parserFields.get(el); + if (fs != null) { + result += fs.size(); + } + } + return result; + } + } + return 0; + } + + public String getXMLString() { + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + try { + Transformer transformer = transformerFactory.newTransformer(); + Element documentElement = doc.getDocumentElement(); + documentElement.setAttribute("xmlns:" + ParsersConfig.PARSER_DISABLED_ATTR.split(":")[0], XMLUtil.IPED_NAMESAPCE); + DOMSource source = new DOMSource(doc); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + StreamResult result = new StreamResult(bos); + transformer.transform(source, result); + String strResult = bos.toString(); + if (strResult.endsWith("?>")) { + return null; + } + return strResult; + } catch (TransformerException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return ""; + } + + @Override + public boolean isLeaf(Object node) { + if (node == ROOT) { + return false; + } else { + if (node instanceof ParserElementName) { + return false; + } + } + return true; + } + + @Override + public void valueForPathChanged(TreePath path, Object newValue) { + // TODO Auto-generated method stub + } + + @Override + public int getIndexOfChild(Object parent, Object child) { + return 0; + } + + @Override + public void addTreeModelListener(TreeModelListener l) { + } + + @Override + public void removeTreeModelListener(TreeModelListener l) { + } + + private HashSet populatesCategoryMimes(Category cat) { + HashSet result = new HashSet(); + result.addAll(cat.getMimes()); + SortedSet subcats = cat.getChildren(); + for (Iterator iterator = subcats.iterator(); iterator.hasNext();) { + Category category = (Category) iterator.next(); + result.addAll(populatesCategoryMimes(category)); + } + categoryMediaType.put(cat, result); + return result; + + } + + private void populateAvailableParsers() { + parsers.clear(); + doc = getDocument(); + + externalParsers = doc.getDocumentElement().getTagName().equals("external-parsers"); + + NodeList nl = doc.getElementsByTagName("parser"); + for (int i = 0; i < nl.getLength(); i++) { + Element e = (Element) nl.item(i); + if (externalParsers) { + Set supportedMimes = null; + + supportedMimes = getSupportedMimeTypes(e); + if (supportedMimes != null) { + parsersMediaType.put(e, supportedMimes); + } + } else { + Set supportedMimes = null; + + supportedMimes = getSupportedMimeTypes(e); + if (supportedMimes != null) { + parsersMediaType.put(e, supportedMimes); + } + } + + parsers.add(e); + } + } + + private Set getSupportedMimeTypes(Element el) { + try { + if (externalParsers) { + Element mimeTypes = (Element) el.getElementsByTagName("mime-types").item(0); + NodeList mimes = mimeTypes.getElementsByTagName("mime-type"); + Set result = new TreeSet(); + for (int i = 0; i < mimes.getLength(); i++) { + Element mimeType = (Element) mimes.item(i); + String[] mime = mimeType.getTextContent().split("/"); + result.add(new MediaType(mime[0], mime[1])); + } + return result; + } else { + String parserClass = el.getAttributes().getNamedItem("class").getNodeValue(); + Class clazz = Class.forName((java.lang.String) parserClass); + Parser parser = (Parser) clazz.newInstance(); + if (parser instanceof MultipleParser) { + MultipleParser mparser = ((MultipleParser) parser); + NodeList mimes = el.getElementsByTagName("mime"); + Set result = new TreeSet(); + for (int i = 0; i < mimes.getLength(); i++) { + String[] mime = ((Element) mimes.item(i)).getTextContent().split("/"); + result.add(new MediaType(mime[0], mime[1])); + } + return result; + } else { + return parser.getSupportedTypes(null); + } + } + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public DocumentBuilder getDocBuilder() throws SAXException, ParserConfigurationException { + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(false); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + docBuilder.setErrorHandler(new ErrorHandler() { + @Override + public void warning(SAXParseException exception) throws SAXException { + } + + @Override + public void fatalError(SAXParseException exception) throws SAXException { + } + + @Override + public void error(SAXParseException exception) throws SAXException { + throw exception; + } + }); + return docBuilder; + } + + public Category getCategory() { + return category; + } + + public void setCategory(Category category) { + this.category = category; + } + + private void updateParsersFields() { + parserFields.clear(); + Class annotation; + try { + annotation = org.apache.tika.config.Field.class; + for (Iterator iterator = parsers.iterator(); iterator.hasNext();) { + Element element = (Element) iterator.next(); + String parserClass = element.getAttributes().getNamedItem("class").getNodeValue(); + Class klass = Class.forName(parserClass); + while (klass != Object.class) { // need to traverse a type hierarchy in order to process methods from super + // types + // iterate though the list of methods declared in the class represented by klass + // variable, and add those annotated with the specified annotation + for (final Field field : klass.getDeclaredFields()) { + if (field.isAnnotationPresent(annotation)) { + AccessController.doPrivileged((PrivilegedAction) () -> { + field.setAccessible(true); + return null; + }); + Annotation annotInstance = field.getAnnotation(annotation); + List fs = parserFields.get(element); + if (fs == null) { + fs = new ArrayList(); + parserFields.put(element, fs); + } + fs.add(field); + } + } + // move to the upper class in the hierarchy in search for more methods + klass = klass.getSuperclass(); + } + } + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private ArrayList updateFilteredParsers(Category category) { + ArrayList filteredParsers = new ArrayList(); + + for (Iterator iterator = parsers.iterator(); iterator.hasNext();) { + Element element = (Element) iterator.next(); + if (category != null) { + Set mts = parsersMediaType.get(element); + if (mts != null) { + for (Iterator iterator2 = mts.iterator(); iterator2.hasNext();) { + MediaType mediaType = (MediaType) iterator2.next(); + if (categoryMediaType.get(category) != null && (categoryMediaType.get(category).contains(mediaType.toString()) || categoryMediaType.get(category).contains(mediaType.getType()))) { + filteredParsers.add(new ParserElementName(element)); + break; + } + } + } + } else { + filteredParsers.add(new ParserElementName(element)); + } + } + SortedSet catChildren = category.getChildren(); + for (Iterator iterator = catChildren.iterator(); iterator.hasNext();) { + Category catChild = (Category) iterator.next(); + updateFilteredParsers(catChild); + } + + categoryParsers.put(category, filteredParsers); + + Collections.sort((List) filteredParsers); + return filteredParsers; + } + + public boolean isExternalParsers() { + return externalParsers; + } + + public Document getDocument() { + if (doc == null) { + String xml = (String) configurable.getConfiguration(); + BOMInputStream bis = new BOMInputStream(new ByteArrayInputStream(xml.getBytes(Charset.forName("UTF-8")))); + try { + doc = PositionalXMLReader.readXML(bis); + } catch (IOException | SAXException e) { + e.printStackTrace(); + } + } + return doc; + } + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/PositionalXMLReader.java b/iped-app/src/main/java/iped/app/home/configurables/PositionalXMLReader.java new file mode 100644 index 0000000000..054d5e0634 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/PositionalXMLReader.java @@ -0,0 +1,92 @@ +package iped.app.home.configurables; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Stack; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xml.sax.Attributes; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +public class PositionalXMLReader { + final static String LINE_NUMBER_KEY_NAME = "lineNumber"; + final static String COLUMN_NUMBER_KEY_NAME = "byteNumber"; + + public static Document readXML(final InputStream is) throws IOException, SAXException { + final Document doc; + SAXParser parser; + try { + final SAXParserFactory factory = SAXParserFactory.newInstance(); + parser = factory.newSAXParser(); + final DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); + final DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); + doc = docBuilder.newDocument(); + } catch (final ParserConfigurationException e) { + throw new RuntimeException("Can't create SAX parser / DOM builder.", e); + } + + final Stack elementStack = new Stack(); + final StringBuilder textBuffer = new StringBuilder(); + final DefaultHandler handler = new DefaultHandler() { + private Locator locator; + + @Override + public void setDocumentLocator(final Locator locator) { + this.locator = locator; // Save the locator, so that it can be used later for line tracking when + // traversing nodes. + } + + @Override + public void startElement(final String uri, final String localName, final String qName, final Attributes attributes) throws SAXException { + addTextIfNeeded(); + final Element el = doc.createElement(qName); + for (int i = 0; i < attributes.getLength(); i++) { + el.setAttribute(attributes.getQName(i), attributes.getValue(i)); + } + el.setUserData(LINE_NUMBER_KEY_NAME, String.valueOf(this.locator.getLineNumber()), null); + el.setUserData(COLUMN_NUMBER_KEY_NAME, String.valueOf(this.locator.getColumnNumber()), null); + elementStack.push(el); + } + + @Override + public void endElement(final String uri, final String localName, final String qName) { + addTextIfNeeded(); + final Element closedEl = elementStack.pop(); + if (elementStack.isEmpty()) { // Is this the root element? + doc.appendChild(closedEl); + } else { + final Element parentEl = elementStack.peek(); + parentEl.appendChild(closedEl); + } + } + + @Override + public void characters(final char ch[], final int start, final int length) throws SAXException { + textBuffer.append(ch, start, length); + } + + // Outputs text accumulated under the current node + private void addTextIfNeeded() { + if (textBuffer.length() > 0) { + final Element el = elementStack.peek(); + final Node textNode = doc.createTextNode(textBuffer.toString()); + el.appendChild(textNode); + textBuffer.delete(0, textBuffer.length()); + } + } + }; + parser.parse(is, handler); + + return doc; + } +} \ No newline at end of file diff --git a/iped-app/src/main/java/iped/app/home/configurables/RegexConfigurablePanel.java b/iped-app/src/main/java/iped/app/home/configurables/RegexConfigurablePanel.java new file mode 100644 index 0000000000..b885f3c71d --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/RegexConfigurablePanel.java @@ -0,0 +1,62 @@ +package iped.app.home.configurables; + +import java.awt.BorderLayout; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import javax.swing.JCheckBox; +import javax.swing.JScrollPane; +import javax.swing.JTextPane; + +import org.apache.commons.lang3.tuple.Pair; + +import iped.app.home.MainFrame; +import iped.configuration.Configurable; +import iped.engine.config.RegexTaskConfig.RegexEntry; +import iped.engine.localization.Messages; + +public class RegexConfigurablePanel extends ConfigurablePanel { + protected JTextPane textArea; + + protected RegexConfigurablePanel(Configurable configurable, MainFrame mainFrame) { + super(configurable, mainFrame); + } + + @Override + public void applyChanges() { + Pair> config = (Pair>) configurable.getConfiguration(); + List list = (List) config.getValue(); + } + + @Override + public void createConfigurableGUI() { + JCheckBox checkField = new JCheckBox(); + Boolean b = ((Pair) configurable.getConfiguration()).getKey(); + checkField.setText(Messages.getString(configurable.getClass().getName() + ".formatMatches", "")); + checkField.setToolTipText(Messages.getString(configurable.getClass().getName() + ".formatMatches.tooltip", "")); + checkField.addChangeListener(e -> { + changed = true; + }); + this.setLayout(new BorderLayout()); + this.add(checkField, BorderLayout.NORTH); + + textArea = new JTextPane(); + textArea.setAutoscrolls(true); + JScrollPane txtAreaScroll = new JScrollPane(); + txtAreaScroll.setViewportView(textArea); + txtAreaScroll.setAutoscrolls(true); + this.add(txtAreaScroll, BorderLayout.CENTER); + + Collection col = (Collection) ((Pair) configurable.getConfiguration()).getValue(); + StringBuffer output = new StringBuffer(); + for (Iterator iterator = col.iterator(); iterator.hasNext();) { + RegexEntry o = (RegexEntry) iterator.next(); + output.append(o.toString()); + output.append("\n"); + } + textArea.setText(output.toString()); + textArea.getDocument().addDocumentListener(this); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/SetCategoryConfigurablePanel.java b/iped-app/src/main/java/iped/app/home/configurables/SetCategoryConfigurablePanel.java new file mode 100644 index 0000000000..1945210d5d --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/SetCategoryConfigurablePanel.java @@ -0,0 +1,488 @@ +package iped.app.home.configurables; + +import java.awt.BorderLayout; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.SortedSet; +import java.util.function.Predicate; + +import javax.swing.DropMode; +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTree; +import javax.swing.ListModel; +import javax.swing.ScrollPaneConstants; +import javax.swing.SwingUtilities; +import javax.swing.TransferHandler; +import javax.swing.event.ListDataListener; +import javax.swing.tree.TreePath; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.tika.mime.MediaType; +import org.apache.tika.mime.MediaTypeRegistry; +import org.eclipse.collections.impl.set.sorted.mutable.TreeSortedSet; +import org.fife.ui.autocomplete.AutoCompletion; +import org.fife.ui.autocomplete.CompletionProvider; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rtextarea.RTextAreaBase; +import org.fife.ui.rtextarea.RTextScrollPane; +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import iped.app.home.MainFrame; +import iped.app.home.configurables.api.ConfigurableValidationException; +import iped.app.home.configurables.autocompletion.MimetypeAutoCompletionProvider; +import iped.app.home.configurables.popups.CategoryTreePopup; +import iped.app.ui.CategoryMimeTreeModel; +import iped.app.ui.Messages; +import iped.app.ui.controls.ConfigCheckBoxTreeCellRenderer; +import iped.engine.config.CategoryConfig; +import iped.engine.config.ConfigurationManager; +import iped.engine.config.SignatureConfig; +import iped.engine.data.Category; + +public class SetCategoryConfigurablePanel extends ConfigurablePanel { + CategoryConfig cc; + private JTree categoryTree; + private JScrollPane treeScrollPanel; + private JList mimeList; + private JScrollPane mimeListScrollPanel; + private CategoryMimeTreeModel ctm; + private List availableMimes; + private CategoryTreePopup categoryTreePopupMenu; + private MouseAdapter popupMa; + private JPanel mimelistPanel; + private RTextAreaBase txMimeFilter; + private CompletionProvider cp; + private JCheckBox ckShowTika; + static final String PATHARRAY_FLAVOR_NAME = "PATHARRAY"; + static final DataFlavor PATHARRAY_FLAVOR = new DataFlavor(int[].class, PATHARRAY_FLAVOR_NAME); + + protected SetCategoryConfigurablePanel(CategoryConfig configurable, MainFrame mainFrame) { + super(configurable, mainFrame); + cc = configurable; + } + + class MimeListModel implements ListModel { + @Override + public int getSize() { + return (int) availableMimes.stream().filter(new Predicate() { + @Override + public boolean test(String t) { + return t.contains(txMimeFilter.getText()); + } + }).count(); + } + + @Override + public String getElementAt(int index) { + return (String) availableMimes.stream().filter(new Predicate() { + @Override + public boolean test(String t) { + return t.contains(txMimeFilter.getText()); + } + }).toArray()[index]; + } + + @Override + public void addListDataListener(ListDataListener l) { + } + + @Override + public void removeListDataListener(ListDataListener l) { + } + + public Object getViewToModelIndex(int i) { + // TODO Auto-generated method stub + return null; + } + } + + @Override + public void createConfigurableGUI() { + ctm = new CategoryMimeTreeModel(cc.getRoot(), true); + categoryTree = new JTree(ctm); + categoryTree.setEditable(true); + categoryTreePopupMenu = new CategoryTreePopup(this); + popupMa = new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (SwingUtilities.isRightMouseButton(e)) { + int row = categoryTree.getClosestRowForLocation(e.getX(), e.getY()); + categoryTree.setLeadSelectionPath(categoryTree.getPathForRow(row)); + if (categoryTree.getLeadSelectionPath().getLastPathComponent() instanceof Category) { + categoryTreePopupMenu.show(e.getComponent(), e.getX(), e.getY()); + } + } + } + }; + categoryTree.addMouseListener(popupMa); + + categoryTree.setCellRenderer(new ConfigCheckBoxTreeCellRenderer(categoryTree, null, new Predicate() { + @Override + public boolean test(Object t) { + return false; + } + })); + + treeScrollPanel = new JScrollPane(); + treeScrollPanel.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + treeScrollPanel.setViewportView(categoryTree); + treeScrollPanel.setAutoscrolls(true); + + this.setLayout(new BorderLayout()); + this.add(treeScrollPanel, BorderLayout.CENTER); + + try { + getAvailableMimetypes(); + mimeList = new JList(new MimeListModel()); + } catch (ParserConfigurationException | SAXException | IOException e) { + e.printStackTrace(); + } + JLabel mimesLabel = new JLabel("Available mime-types:"); + txMimeFilter = new RSyntaxTextArea(1, 20); + txMimeFilter.setHighlightCurrentLine(false); + txMimeFilter.addKeyListener(new KeyListener() { + @Override + public void keyTyped(KeyEvent e) { + mimeList.setModel(new MimeListModel()); + } + + @Override + public void keyReleased(KeyEvent e) { + } + + @Override + public void keyPressed(KeyEvent e) { + } + }); + cp = new MimetypeAutoCompletionProvider(); + AutoCompletion ac = new AutoCompletion(cp); + ac.install(txMimeFilter); + + mimelistPanel = new JPanel(new BorderLayout()); + mimelistPanel.setBackground(this.getBackground()); + // mimelistPanel.add(mimesLabel,BorderLayout.BEFORE_FIRST_LINE); + RTextScrollPane tsMimeFilter = new RTextScrollPane(txMimeFilter); + tsMimeFilter.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); + tsMimeFilter.setLineNumbersEnabled(false); + mimelistPanel.add(tsMimeFilter, BorderLayout.NORTH); + mimeListScrollPanel = new JScrollPane(); + mimeListScrollPanel.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + mimeListScrollPanel.setViewportView(mimeList); + mimeListScrollPanel.setAutoscrolls(true); + mimeList.setDropMode(DropMode.ON); + mimeList.setTransferHandler(new MimeListTransferHandler()); + mimelistPanel.add(mimeListScrollPanel, BorderLayout.CENTER); + ckShowTika = new JCheckBox(); + ckShowTika.setText(Messages.get("Home.IPEDMimeSeachList.showTikaMimeTypes")); + ckShowTika.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + try { + getAvailableMimetypes(); + } catch (ParserConfigurationException | SAXException | IOException e1) { + e1.printStackTrace(); + } + mimeList.setModel(new MimeListModel()); + } + }); + mimelistPanel.add(ckShowTika, BorderLayout.SOUTH); + this.add(mimelistPanel, BorderLayout.WEST); + + mimeList.setDragEnabled(true); + categoryTree.setDropMode(DropMode.ON); + categoryTree.setDragEnabled(true); + categoryTree.setTransferHandler(new CategoryTreeTransferHandler()); + + } + + class CategoryTreeTransferHandler extends TransferHandler { + public boolean canImport(TransferHandler.TransferSupport info) { + if (!info.isDataFlavorSupported(DataFlavor.stringFlavor) && !info.isDataFlavorSupported(PATHARRAY_FLAVOR)) { + return false; + } + return true; + } + + public int getSourceActions(JComponent c) { + return TransferHandler.MOVE; + } + + public boolean importData(TransferHandler.TransferSupport info) { + if (!info.isDrop()) { + return false; + } + + boolean modelChanged = false; + + if (info.isDataFlavorSupported(DataFlavor.stringFlavor)) { + TreePath path = categoryTree.getPathForLocation(info.getDropLocation().getDropPoint().x, info.getDropLocation().getDropPoint().y); + if (path.getLastPathComponent() instanceof Category) { + Category cat = (Category) path.getLastPathComponent(); + int[] selind = mimeList.getSelectedIndices(); + for (int i = 0; i < selind.length; i++) { + String mime = mimeList.getModel().getElementAt(selind[i]); + availableMimes.remove(mimeList.getModel().getElementAt(selind[i])); + cat.getMimes().add(mime); + } + + // refreshs mimeList + mimeList.setModel(new MimeListModel()); + + modelChanged = true; + } + } else if (info.isDataFlavorSupported(PATHARRAY_FLAVOR)) { + TreePath[] paths = categoryTree.getSelectionPaths(); + TreePath dstpath = categoryTree.getPathForLocation(info.getDropLocation().getDropPoint().x, info.getDropLocation().getDropPoint().y); + if (dstpath.getLastPathComponent() instanceof Category) { + Category dstcat = (Category) dstpath.getLastPathComponent(); + for (int i = 0; i < paths.length; i++) { + if (paths[i].getLastPathComponent() instanceof Category) { + Category cat = (Category) paths[i].getLastPathComponent(); + Category parent = cat.getParent(); + parent.getChildren().remove(cat); + dstcat.getChildren().add(cat); + } + if (paths[i].getLastPathComponent() instanceof String) { + String mime = (String) paths[i].getLastPathComponent(); + dstcat.getMimes().add(mime); + Category cat = (Category) paths[i].getParentPath().getLastPathComponent(); + cat.getMimes().remove(mime); + } + } + } + modelChanged = true; + } + + if (modelChanged) { + refreshModel(); + } + + changed = true; + + return modelChanged; + } + + @Override + protected Transferable createTransferable(JComponent c) { + return new Transferable() { + public boolean isDataFlavorSupported(DataFlavor flavor) { + return flavor.equals(PATHARRAY_FLAVOR); + } + + @Override + public DataFlavor[] getTransferDataFlavors() { + DataFlavor[] dataFlavors = new DataFlavor[1]; + dataFlavors[0] = PATHARRAY_FLAVOR; + return dataFlavors; + } + + @Override + public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { + return categoryTree.getSelectionPaths();// attention that transfer data pass copies of the objects not references to it + } + }; + } + + } + + class MimeListTransferHandler extends TransferHandler { + public boolean canImport(TransferHandler.TransferSupport info) { + if (!info.isDataFlavorSupported(DataFlavor.stringFlavor) && !info.isDataFlavorSupported(PATHARRAY_FLAVOR)) { + return false; + } + return true; + } + + public int getSourceActions(JComponent c) { + return TransferHandler.MOVE; + } + + public boolean importData(TransferHandler.TransferSupport info) { + if (!info.isDrop()) { + return false; + } + + boolean modelChanged = false; + + if (info.isDataFlavorSupported(PATHARRAY_FLAVOR)) { + TreePath[] paths = categoryTree.getSelectionPaths(); + boolean thereAreCategories = false; + // first loop to check if there is any category to be removed + for (int i = 0; i < paths.length; i++) { + if (paths[i].getLastPathComponent() instanceof Category) { + thereAreCategories = true; + break; + } + } + if (thereAreCategories) { + int result = JOptionPane.showConfirmDialog(mainFrame, "Do you really want to remove selected categories?", "Category remoaval", JOptionPane.OK_CANCEL_OPTION); + + if (result != JOptionPane.OK_OPTION) { + return false; + } + } + + for (int i = 0; i < paths.length; i++) { + if (paths[i].getLastPathComponent() instanceof Category) { + Category cat = (Category) paths[i].getLastPathComponent(); + Category parent = cat.getParent(); + parent.getChildren().remove(cat); + recursiveMoveMime(cat); + } + if (paths[i].getLastPathComponent() instanceof String) { + String mime = (String) paths[i].getLastPathComponent(); + Category cat = (Category) paths[i].getParentPath().getLastPathComponent(); + cat.getMimes().remove(mime); + availableMimes.add(mime); + } + } + + // refreshs mimeList + Collections.sort(availableMimes); + mimeList.setModel(new MimeListModel()); + modelChanged = true; + } + + if (modelChanged) { + refreshModel(); + } + + changed = true; + + return modelChanged; + } + + @Override + protected Transferable createTransferable(JComponent c) { + return new Transferable() { + public boolean isDataFlavorSupported(DataFlavor flavor) { + return flavor.equals(DataFlavor.stringFlavor); + } + + @Override + public DataFlavor[] getTransferDataFlavors() { + DataFlavor[] dataFlavors = new DataFlavor[1]; + dataFlavors[0] = DataFlavor.stringFlavor; + return dataFlavors; + } + + @Override + public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { + return mimeList.getSelectedValue(); + } + }; + } + } + + private void recursiveMoveMime(Category cat) { + List mimes = cat.getMimes(); + for (Iterator iterator2 = mimes.iterator(); iterator2.hasNext();) { + String mime = (String) iterator2.next(); + availableMimes.add(mime); + } + Set children = cat.getChildren(); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + Category category = (Category) iterator.next(); + recursiveMoveMime(category); + } + } + + public void refreshModel() { + // update tree model + Enumeration exps = categoryTree.getExpandedDescendants(categoryTree.getPathForRow(0)); + categoryTree.setModel(new CategoryMimeTreeModel(cc.getRoot(), true)); + while (exps.hasMoreElements()) { + TreePath curpath = exps.nextElement(); + categoryTree.expandPath(curpath); + } + } + + private List getAvailableMimetypes() throws ParserConfigurationException, SAXException, IOException { + SignatureConfig sc = ConfigurationManager.get().findObject(SignatureConfig.class); + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + String xml = sc.getConfiguration(); + ByteArrayInputStream bis = new ByteArrayInputStream(xml.getBytes(Charset.forName("UTF-8"))); + Document doc = docBuilder.parse(bis); + + SortedSet mimes = new TreeSortedSet(); + NodeList nl = doc.getElementsByTagName("mime-type"); + for (int i = 0; i < nl.getLength(); i++) { + String mime = nl.item(i).getAttributes().getNamedItem("type").getNodeValue(); + if (!isIncluded(cc.getRoot(), mime)) { + mimes.add(mime); + } + } + + if (ckShowTika != null && ckShowTika.isSelected()) { + SortedSet mts = MediaTypeRegistry.getDefaultRegistry().getTypes(); + for (Iterator iterator = mts.iterator(); iterator.hasNext();) { + MediaType mediaType = (MediaType) iterator.next(); + if (!isIncluded(cc.getRoot(), mediaType.toString())) { + mimes.add(mediaType.toString()); + } + } + } + + this.availableMimes = new ArrayList(); + this.availableMimes.addAll(mimes); + + return this.availableMimes; + } + + private boolean isIncluded(Category cat, String mime) { + if (cat.getMimes().contains(mime)) { + return true; + } else { + SortedSet cats = cat.getChildren(); + if (cats != null && cats.size() > 0) { + for (Iterator iterator = cats.iterator(); iterator.hasNext();) { + Category category = (Category) iterator.next(); + if (isIncluded(category, mime)) { + return true; + } + } + return false; + } else { + return false; + } + } + } + + @Override + public void applyChanges() throws ConfigurableValidationException { + } + + public JTree getCategoryTree() { + return categoryTree; + } + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/StringSetConfigurablePanel.java b/iped-app/src/main/java/iped/app/home/configurables/StringSetConfigurablePanel.java new file mode 100644 index 0000000000..8ca2ffe0cb --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/StringSetConfigurablePanel.java @@ -0,0 +1,47 @@ +package iped.app.home.configurables; + +import java.util.Collection; +import java.util.Iterator; + +import iped.app.home.MainFrame; +import iped.configuration.Configurable; + +public class StringSetConfigurablePanel extends TextConfigurablePanel { + + private static final long serialVersionUID = 6101850157753514466L; + + protected StringSetConfigurablePanel(Configurable configurable, MainFrame mainFrame) { + super(configurable, mainFrame); + } + + @Override + public void createConfigurableGUI() { + super.createConfigurableGUI(); + Collection col = (Collection) configurable.getConfiguration(); + StringBuffer output = new StringBuffer(); + for (Iterator iterator = col.iterator(); iterator.hasNext();) { + String string = (String) iterator.next(); + output.append(string); + output.append("\n"); + } + textArea.getDocument().removeDocumentListener(this); + textArea.setText(output.toString()); + textArea.getDocument().addDocumentListener(this); + } + + @Override + public void applyChanges() { + Collection col = (Collection) configurable.getConfiguration(); + col.removeAll(col); + + String content = textArea.getText(); + for (String line : content.split("\n")) { //$NON-NLS-1$ + line = line.trim(); + if (line.startsWith("#") || line.isEmpty()) { //$NON-NLS-1$ + continue; + } + col.add(line); + } + } + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/TextConfigurablePanel.java b/iped-app/src/main/java/iped/app/home/configurables/TextConfigurablePanel.java new file mode 100644 index 0000000000..cb9d0d3da3 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/TextConfigurablePanel.java @@ -0,0 +1,41 @@ +package iped.app.home.configurables; + +import java.awt.BorderLayout; + +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rtextarea.RTextScrollPane; + +import iped.app.home.MainFrame; +import iped.app.home.configurables.api.ConfigurableValidationException; +import iped.configuration.Configurable; + +public class TextConfigurablePanel extends ConfigurablePanel { + + // protected RegexTextPane textArea; + protected RSyntaxTextArea textArea; + protected RTextScrollPane txtAreaScroll; + + protected TextConfigurablePanel(Configurable configurable, MainFrame mainFrame) { + super(configurable, mainFrame); + } + + public void createConfigurableGUI() { + textArea = new RSyntaxTextArea(20, 60); + + textArea.setAutoscrolls(true); + textArea.setText(configurable.getConfiguration().toString()); + textArea.getDocument().addDocumentListener(this); + txtAreaScroll = new RTextScrollPane(); + txtAreaScroll.setViewportView(textArea); + txtAreaScroll.setAutoscrolls(true); + txtAreaScroll.setLineNumbersEnabled(true); + this.setLayout(new BorderLayout()); + this.add(txtAreaScroll, BorderLayout.CENTER); + } + + @Override + public void applyChanges() throws ConfigurableValidationException { + ((Configurable) configurable).setConfiguration(textArea.getText()); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/UTF8PropertiesConfigurablePanel.java b/iped-app/src/main/java/iped/app/home/configurables/UTF8PropertiesConfigurablePanel.java new file mode 100644 index 0000000000..b2e9b901d8 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/UTF8PropertiesConfigurablePanel.java @@ -0,0 +1,265 @@ +package iped.app.home.configurables; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.Iterator; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; + +import javax.swing.BorderFactory; +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSpinner; +import javax.swing.JTextArea; +import javax.swing.JTextField; +import javax.swing.border.Border; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.text.JTextComponent; + +import iped.app.home.MainFrame; +import iped.configuration.Configurable; +import iped.engine.config.IPropertiesConfigurable; +import iped.engine.localization.Messages; +import iped.utils.UTF8Properties; + +public class UTF8PropertiesConfigurablePanel extends ConfigurablePanel implements ItemListener { + TreeMap textFieldList = new TreeMap(); + + public UTF8PropertiesConfigurablePanel(Configurable configurable, MainFrame mainFrame) { + super(configurable, mainFrame); + } + + public void createConfigurableGUI() { + JPanel contentPanel = new JPanel(new GridBagLayout()); + contentPanel.setBackground(Color.white); + UTF8Properties config = (UTF8Properties) configurable.getConfiguration(); + int currentLine = 0; + if (config != null) { + for (Object propertie : config.orderedKeySet()) { + Object value = config.get(propertie); + JComponent c = null; + String localizedName = Messages.getString(configurable.getClass().getName() + "." + propertie, propertie.toString()); + + // create label + contentPanel.add(new JLabel(localizedName + ":"), getGridBagConstraints(0, currentLine, 1, 0)); + // create input + if (value != null) { + Type t = getFieldType(configurable, propertie.toString()); + if (t != null) { + if (t.getTypeName().equals("int") || t.getTypeName().equals("long")) { + try { + boolean hasDefaultValue = hasDefaultValue(configurable, propertie.toString()); + JSpinner spinner; + if (!hasDefaultValue) { + spinner = new JSpinner(); + int ivalue = Integer.parseInt(value.toString().trim()); + spinner.setValue(ivalue); + } else { + spinner = new JSpinner(); + AutoCalcSpinnerModel model = new AutoCalcSpinnerModel(spinner); + spinner.setModel(model); + if (!value.toString().equals("auto")) { + int ivalue = Integer.parseInt(value.toString().trim()); + spinner.setValue(ivalue); + } else { + spinner.setValue(0); + } + } + spinner.getModel().addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + changed = true; + fireChangeListener(e); + } + }); + c = spinner; + } catch (NumberFormatException ne) { + } + } + if (t.getTypeName().equals("boolean") || t.getTypeName().equals("java.lang.Boolean") + || (t.getTypeName().equals("java.lang.String") && (value.toString().trim().equals("true") || value.toString().trim().equals("false")))) { + boolean bvalue = value.toString().trim().equals("true"); + JCheckBox cb = new JCheckBox(); + cb.setSelected(bvalue); + cb.addItemListener(this); + c = cb; + } + } else { + if (value.toString().trim().equals("true") || value.toString().trim().equals("false")) { + boolean bvalue = value.toString().trim().equals("true"); + JCheckBox cb = new JCheckBox(); + cb.setSelected(bvalue); + cb.addItemListener(this); + c = cb; + } + } + if (c == null) { + if (value == null) { + JTextField textField = new JTextField((value != null) ? value.toString() : ""); + textField.getDocument().addDocumentListener(this); + c = textField; + } else { + if (value.toString().length() > 100) { + JTextArea textArea = new JTextArea((value != null) ? value.toString() : ""); + textArea.getDocument().addDocumentListener(this); + textArea.setLineWrap(true); + Border border = BorderFactory.createLineBorder(Color.BLACK); + textArea.setBorder(border); + c = textArea; + } else { + JTextField textField = new JTextField((value != null) ? value.toString() : ""); + textField.getDocument().addDocumentListener(this); + c = textField; + } + } + } + } + contentPanel.add(c, getGridBagConstraints(1, currentLine, 1, 1)); + String tooltipKey = configurable.getClass().getName() + "." + propertie + Messages.TOOLTIP_SUFFIX; + try { + String toolTipText = Messages.getString(tooltipKey, config.getComments(propertie)); + if (toolTipText != null) { + c.setToolTipText(toolTipText); + } + } catch (Exception e) { + // tooltip does not exists in resources + } + // + textFieldList.put(propertie, c); + currentLine++; + } + } else { + contentPanel.add(new JLabel("No content!!"), getGridBagConstraints(0, currentLine, 1, 1)); + } + + JPanel backPanel = new JPanel(); + backPanel.setBackground(contentPanel.getBackground()); + backPanel.setLayout(new BorderLayout()); + backPanel.add(contentPanel, BorderLayout.NORTH); + + JScrollPane contentScrollPanel = new JScrollPane(); + contentScrollPanel.setAlignmentY(TOP_ALIGNMENT); + contentScrollPanel.setViewportView(backPanel); + contentScrollPanel.setAutoscrolls(true); + this.setLayout(new BorderLayout()); + this.add(contentScrollPanel, BorderLayout.CENTER); + } + + private Type getFieldType(Configurable configurable, String propertyName) { + try { + Field f = configurable.getClass().getField(propertyName); + return f.getType(); + } catch (NoSuchFieldException | SecurityException e) { + } + String accessName = propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1); + try { + Method m = configurable.getClass().getMethod("get" + accessName, null); + return m.getGenericReturnType(); + } catch (NoSuchMethodException | SecurityException e) { + } + try { + Method m = configurable.getClass().getMethod("is" + accessName, null); + return m.getGenericReturnType(); + } catch (NoSuchMethodException | SecurityException e) { + } + try { + Method m = configurable.getClass().getMethod("isTo" + accessName, null); + return m.getGenericReturnType(); + } catch (NoSuchMethodException | SecurityException e) { + } + + return null; + } + + private Class getType(Configurable configurable, String propertyName) { + try { + Field f = configurable.getClass().getField(propertyName); + return f.getType(); + } catch (NoSuchFieldException | SecurityException e) { + } + String accessName = propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1); + try { + Method m = configurable.getClass().getMethod("get" + accessName, null); + return m.getReturnType(); + } catch (NoSuchMethodException | SecurityException e) { + } + try { + Method m = configurable.getClass().getMethod("is" + accessName, null); + return m.getReturnType(); + } catch (NoSuchMethodException | SecurityException e) { + } + try { + Method m = configurable.getClass().getMethod("isTo" + accessName, null); + return m.getReturnType(); + } catch (NoSuchMethodException | SecurityException e) { + } + return null; + } + + private boolean hasDefaultValue(Configurable configurable, String propertyName) { + String accessName = propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1); + try { + Method m = configurable.getClass().getMethod("getDefault" + accessName, null); + return true; + } catch (NoSuchMethodException | SecurityException e) { + } + return false; + } + + private GridBagConstraints getGridBagConstraints(int tableColumnIndex, int tableLineIndex, int cellWidth, double weightX) { + GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = weightX; + c.gridx = tableColumnIndex; + c.gridy = tableLineIndex; + c.gridwidth = cellWidth; + c.gridheight = 1; + c.insets = new Insets(2, 10, 2, 10); + return c; + } + + @Override + public void applyChanges() { + UTF8Properties config = (UTF8Properties) configurable.getConfiguration(); + if (config != null) { + Set> es = config.entrySet(); + for (Iterator> iterator = es.iterator(); iterator.hasNext();) { + Entry e = iterator.next(); + JComponent c = textFieldList.get(e.getKey()); + if (c instanceof JTextComponent) { + JTextComponent textField = (JTextComponent) c; + config.setProperty(e.getKey().toString(), textField.getText()); + } + if (c instanceof JCheckBox) { + JCheckBox cb = (JCheckBox) c; + config.setProperty(e.getKey().toString(), Boolean.toString(cb.isSelected())); + } + if (c instanceof JSpinner) { + JSpinner spinner = (JSpinner) c; + config.setProperty(e.getKey().toString(), spinner.getValue().toString()); + } + } + ((IPropertiesConfigurable) configurable).processProperties(config); + } + } + + @Override + public void itemStateChanged(ItemEvent e) { + changed = true; + fireChangeListener(new ChangeEvent(e.getSource())); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/XMLCarverConfigurablePanel.java b/iped-app/src/main/java/iped/app/home/configurables/XMLCarverConfigurablePanel.java new file mode 100644 index 0000000000..c6c0957945 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/XMLCarverConfigurablePanel.java @@ -0,0 +1,149 @@ +package iped.app.home.configurables; + +import java.awt.Color; +import java.awt.Component; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.io.IOException; +import java.util.List; + +import javax.swing.AbstractListModel; +import javax.swing.JList; +import javax.swing.JScrollPane; +import javax.swing.ListSelectionModel; +import javax.swing.ScrollPaneConstants; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.xml.parsers.ParserConfigurationException; + +import org.fife.ui.rsyntaxtextarea.AbstractTokenMakerFactory; +import org.fife.ui.rsyntaxtextarea.SyntaxScheme; +import org.fife.ui.rsyntaxtextarea.TokenMakerFactory; +import org.xml.sax.SAXException; + +import iped.app.home.MainFrame; +import iped.app.home.configurables.api.ConfigurableValidationException; +import iped.app.ui.Messages; +import iped.app.ui.controls.textarea.XMLXSDTokenMaker; +import iped.carvers.api.CarverType; +import iped.configuration.Configurable; +import iped.engine.task.carver.XMLCarverConfiguration; + +public class XMLCarverConfigurablePanel extends AdvancedTextConfigurablePanel { + XMLCarverConfiguration config; + private JScrollPane carverListPanel; + private JList carverTypeList; + String maxStringToComputeTheWidth; + private CarverConfigCellRenderer cellRenderer; + + static { + AbstractTokenMakerFactory atmf = (AbstractTokenMakerFactory) TokenMakerFactory.getDefaultInstance(); + atmf.putMapping(XMLXSDTokenMaker.SYNTAX_STYLE_XMLXSD, "iped.app.ui.controls.textarea.XMLXSDTokenMaker"); + } + + protected XMLCarverConfigurablePanel(Configurable configurable, MainFrame mainFrame) { + super(configurable, mainFrame); + config = configurable.getConfiguration(); + } + + @Override + public void createConfigurableGUI() { + super.createConfigurableGUI(); + + textArea.getDocument().removeDocumentListener(this); + textArea.setSyntaxEditingStyle(XMLXSDTokenMaker.SYNTAX_STYLE_XMLXSD); + SyntaxScheme scheme = textArea.getSyntaxScheme(); + scheme.getStyle(XMLXSDTokenMaker.RESERVED_WORD).background = Color.pink; + scheme.getStyle(XMLXSDTokenMaker.RESERVED_WORD).underline = true; + textArea.setText(config.getXMLString()); + textArea.getDocument().addDocumentListener(this); + } + + class ResizeListener extends ComponentAdapter { + public void componentResized(ComponentEvent e) { + int ncols = (int) Math.floor((carverListPanel.getSize().getWidth()) / cellRenderer.getMaxStringWidth()); + int nrows = (int) Math.ceil((double) carverTypeList.getModel().getSize() / (double) ncols); + + carverTypeList.setVisibleRowCount(nrows); + carverListPanel.setViewportView(carverTypeList); + } + + @Override + public void componentShown(ComponentEvent e) { + componentResized(e); + } + } + + public void createCarverListPanel() { + carverListPanel = new JScrollPane(); + carverTypeList = new JList(config.getAvailableCarverTypes()); + carverTypeList.setLayoutOrientation(JList.HORIZONTAL_WRAP); + carverListPanel.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + this.addComponentListener(new ResizeListener()); + carverListPanel.setViewportView(carverTypeList); + carverListPanel.setAutoscrolls(true); + cellRenderer = new CarverConfigCellRenderer(); + carverTypeList.setCellRenderer(cellRenderer); + carverTypeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + carverTypeList.addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + if (!carverTypeList.getValueIsAdjusting()) { + CarverType ct = (CarverType) carverTypeList.getSelectedValue(); + if (ct != null) { + config.setEnableCarverType(ct, !ct.isEnabled()); + textArea.setText(config.getXMLString()); + changed = true; + carverTypeList.setValueIsAdjusting(true); + try { + carverTypeList.clearSelection(); + } finally { + carverTypeList.setValueIsAdjusting(false); + } + } + } + } + }); + } + + class CarverTypeListModel extends AbstractListModel { + List source; + + public CarverTypeListModel(List source) { + this.source = source; + } + + @Override + public int getSize() { + return source.size(); + } + + @Override + public CarverType getElementAt(int index) { + return source.get(index); + } + } + + @Override + public void applyChanges() throws ConfigurableValidationException { + try { + config.loadXMLConfigFile(textArea.getText()); + carverTypeList.setModel(new CarverTypeListModel(config.getAvailableCarverTypesList())); + } catch (IOException | SAXException | ParserConfigurationException e) { + throw new ConfigurableValidationException("Erro de sintaxe no XML", e); + } + } + + protected String getBasicPaneTitle() { + return Messages.get("Home.configurables.BasicCarverPanelLabel"); + } + + @Override + protected Component getBasicPane() { + if (carverListPanel == null) { + createCarverListPanel(); + } + return carverListPanel; + } + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/XMLConfigurablePanel.java b/iped-app/src/main/java/iped/app/home/configurables/XMLConfigurablePanel.java new file mode 100644 index 0000000000..20ee2dec4b --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/XMLConfigurablePanel.java @@ -0,0 +1,96 @@ +package iped.app.home.configurables; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.net.URL; +import java.nio.charset.Charset; + +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; + +import org.fife.ui.rsyntaxtextarea.SyntaxConstants; +import org.w3c.dom.Document; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +import iped.app.home.MainFrame; +import iped.app.home.configurables.api.ConfigurableValidationException; +import iped.app.ui.controls.textarea.XmlEditorKit; +import iped.configuration.Configurable; + +public class XMLConfigurablePanel extends TextConfigurablePanel { + String xml; + URL schemaUrl; + + protected XMLConfigurablePanel(Configurable configurable, MainFrame mainFrame) { + this(configurable, null, mainFrame); + } + + protected XMLConfigurablePanel(Configurable configurable, URL schemaUrl, MainFrame mainFrame) { + super(configurable, mainFrame); + xml = configurable.getConfiguration(); + this.schemaUrl = schemaUrl; + } + + @Override + public void createConfigurableGUI() { + super.createConfigurableGUI(); + textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_XML); + textArea.setCodeFoldingEnabled(true); + + XmlEditorKit xek = new XmlEditorKit(); + if (this.schemaUrl != null) { + xek.setSchema(schemaUrl); + } + // textArea.setEditorKitForContentType("text/xml", xek); + // textArea.setContentType("text/xml"); + textArea.getDocument().removeDocumentListener(this); + textArea.setText(xml); + textArea.getDocument().addDocumentListener(this); + + } + + public DocumentBuilder getDocBuilder() throws SAXException, ParserConfigurationException { + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + if (schemaUrl != null) { + Schema schema = factory.newSchema(schemaUrl); + dbf.setSchema(schema); + } + dbf.setNamespaceAware(true); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + docBuilder.setErrorHandler(new ErrorHandler() { + @Override + public void warning(SAXParseException exception) throws SAXException { + } + + @Override + public void fatalError(SAXParseException exception) throws SAXException { + } + + @Override + public void error(SAXParseException exception) throws SAXException { + throw exception; + } + }); + return docBuilder; + } + + @Override + public void applyChanges() throws ConfigurableValidationException { + try { + xml = textArea.getText(); + ByteArrayInputStream bis = new ByteArrayInputStream(xml.getBytes(Charset.forName("UTF-8"))); + Document doc = getDocBuilder().parse(bis); + ((Configurable) configurable).setConfiguration(xml); + } catch (IOException | SAXException | ParserConfigurationException e) { + throw new ConfigurableValidationException("Erro de sintaxe no XML", e); + } + } + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/api/ConfigurableValidationException.java b/iped-app/src/main/java/iped/app/home/configurables/api/ConfigurableValidationException.java new file mode 100644 index 0000000000..2f2784c7ca --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/api/ConfigurableValidationException.java @@ -0,0 +1,13 @@ +package iped.app.home.configurables.api; + +public class ConfigurableValidationException extends Exception { + + public ConfigurableValidationException(String msg, Exception cause) { + super(msg, cause); + } + + public ConfigurableValidationException(Exception cause) { + super(cause); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/api/IConfigurablePanel.java b/iped-app/src/main/java/iped/app/home/configurables/api/IConfigurablePanel.java new file mode 100644 index 0000000000..636915764c --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/api/IConfigurablePanel.java @@ -0,0 +1,39 @@ +package iped.app.home.configurables.api; + +import java.awt.Component; + +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +public interface IConfigurablePanel { + /** + * Internal UI components initialization method + */ + void createConfigurableGUI(); + + /** + * Returns a reference to the main UI component. Used to install on App UI. + */ + Component getPanel(); + + /** + * Checks if UI has changed the configurable. + */ + boolean hasChanged(); + + /** + * Effectivelly saves the changes done in configurable object. + */ + void applyChanges() throws ConfigurableValidationException;; + + /** + * Register a listener to configurable object change. + */ + void fireChangeListener(ChangeEvent changeEvent); + + /** + * Register a listener to configurable object change. + */ + void addChangeListener(ChangeListener changeListener); + +} \ No newline at end of file diff --git a/iped-app/src/main/java/iped/app/home/configurables/api/IConfigurablePanelFactory.java b/iped-app/src/main/java/iped/app/home/configurables/api/IConfigurablePanelFactory.java new file mode 100644 index 0000000000..17a43148f7 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/api/IConfigurablePanelFactory.java @@ -0,0 +1,21 @@ +package iped.app.home.configurables.api; + +import iped.app.home.MainFrame; +import iped.configuration.Configurable; +import iped.engine.task.AbstractTask; + +public interface IConfigurablePanelFactory { + + /** + * Factory method to instantiate an ConfigurablePanel suitable to the + * configurable object + * + * @param configurable + * - the configurable object that the created ConfigurablePanel will + * handle. + * @param mainFrame + * - the main frame of the panel. + */ + public IConfigurablePanel createConfigurablePanel(AbstractTask task, Configurable configurable, MainFrame mainFrame); + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/autocompletion/CharsetCompletionProvider.java b/iped-app/src/main/java/iped/app/home/configurables/autocompletion/CharsetCompletionProvider.java new file mode 100644 index 0000000000..f109b9b10a --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/autocompletion/CharsetCompletionProvider.java @@ -0,0 +1,28 @@ +package iped.app.home.configurables.autocompletion; + +import java.nio.charset.Charset; +import java.util.Iterator; +import java.util.SortedMap; + +import org.fife.ui.autocomplete.BasicCompletion; +import org.fife.ui.autocomplete.DefaultCompletionProvider; + +public class CharsetCompletionProvider extends DefaultCompletionProvider { + + public CharsetCompletionProvider() { + super(); + SortedMap charsets = Charset.availableCharsets(); + if (charsets != null) { + for (Iterator iterator = charsets.keySet().iterator(); iterator.hasNext();) { + String charsetName = (String) iterator.next(); + this.addCompletion(new BasicCompletion(this, charsetName)); + } + } + } + + @Override + protected boolean isValidChar(char ch) { + return super.isValidChar(ch) || ch == '/' || ch == '-' || ch == '.' || ch == '-' || ch == '=' || ch == '+' || ch == ';'; + } + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/autocompletion/MimetypeAutoCompletionProvider.java b/iped-app/src/main/java/iped/app/home/configurables/autocompletion/MimetypeAutoCompletionProvider.java new file mode 100644 index 0000000000..02943debf2 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/autocompletion/MimetypeAutoCompletionProvider.java @@ -0,0 +1,86 @@ +package iped.app.home.configurables.autocompletion; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.SortedSet; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.tika.mime.MediaType; +import org.apache.tika.mime.MediaTypeRegistry; +import org.eclipse.collections.impl.set.sorted.mutable.TreeSortedSet; +import org.fife.ui.autocomplete.BasicCompletion; +import org.fife.ui.autocomplete.DefaultCompletionProvider; +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import iped.engine.config.ConfigurationManager; +import iped.engine.config.SignatureConfig; + +public class MimetypeAutoCompletionProvider extends DefaultCompletionProvider { + + private ArrayList keywords; + + public MimetypeAutoCompletionProvider() { + super(); + + TreeSortedSet mimes = null; + try { + mimes = getCustomMimetypes(); + keywords = new ArrayList(); + if (mimes != null) { + keywords.addAll(mimes); + } + SortedSet mts = MediaTypeRegistry.getDefaultRegistry().getTypes(); + for (Iterator iterator = mts.iterator(); iterator.hasNext();) { + MediaType mediaType = (MediaType) iterator.next(); + keywords.add(mediaType.toString()); + } + Collections.sort(keywords); + + for (Iterator iterator = keywords.iterator(); iterator.hasNext();) { + String mediaType = (String) iterator.next(); + this.addCompletion(new BasicCompletion(this, mediaType)); + } + } catch (ParserConfigurationException | SAXException | IOException e) { + e.printStackTrace(); + } + + } + + private TreeSortedSet getCustomMimetypes() throws ParserConfigurationException, SAXException, IOException { + SignatureConfig sc = ConfigurationManager.get().findObject(SignatureConfig.class); + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + String xml = sc.getConfiguration(); + ByteArrayInputStream bis = new ByteArrayInputStream(xml.getBytes(Charset.forName("UTF-8"))); + Document doc = docBuilder.parse(bis); + + TreeSortedSet mimes = new TreeSortedSet(); + NodeList nl = doc.getElementsByTagName("mime-type"); + for (int i = 0; i < nl.getLength(); i++) { + String mime = nl.item(i).getAttributes().getNamedItem("type").getNodeValue(); + mimes.add(mime); + } + return mimes; + } + + @Override + protected boolean isValidChar(char ch) { + return super.isValidChar(ch) || ch == '/' || ch == '-' || ch == '.' || ch == '-' || ch == '=' || ch == '+' || ch == ';'; + } + + public boolean containsKeyword(String string) { + return keywords.contains(string); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/bean/BeanConfigurablePanel.java b/iped-app/src/main/java/iped/app/home/configurables/bean/BeanConfigurablePanel.java new file mode 100644 index 0000000000..c85469659c --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/bean/BeanConfigurablePanel.java @@ -0,0 +1,211 @@ +package iped.app.home.configurables.bean; + +import java.awt.Component; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JScrollPane; +import javax.swing.JTextField; +import javax.swing.SpringLayout; + +import org.apache.commons.lang3.tuple.Pair; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import iped.app.home.MainFrame; +import iped.app.home.configurables.ConfigurablePanel; +import iped.app.ui.controls.textarea.RegexTextPane; +import iped.configuration.Configurable; + +public class BeanConfigurablePanel extends ConfigurablePanel { + private ArrayList comps; + private JLabel largestLabel; + private JLabel lastLabel; + private int max; + + public BeanConfigurablePanel(Configurable configurable, MainFrame mainFrame) { + super(configurable, mainFrame); + } + + /** + * Creates the suitable ui input to manipulate the specific property + * + * @param config + * - the instance of the bean which property will be manipulated by + * the input + * @param pd + * - the property descriptor of the property for which will be + * created the ui input + */ + private JComponent createInputForProperty(Object config, PropertyDescriptor pd) { + Object o = null; + try { + o = pd.getReadMethod().invoke(config); + } catch (Exception e) { + e.printStackTrace(); + } + return createInputForObject(o); + } + + /** + * Creates an layout the UI fields for the bean manipulation + * + * @param config + * - the instance of the bean which property will be manipulated by + * the input + */ + public void createBeanGUI(Object config) throws IntrospectionException { + if (config instanceof Collection) { + Collection col = (Collection) config; + for (Iterator iterator = col.iterator(); iterator.hasNext();) { + Object object = (Object) iterator.next(); + createBeanGUI(object); + } + + return; + } + + property: for (PropertyDescriptor pd : Introspector.getBeanInfo(config.getClass()).getPropertyDescriptors()) { + if (pd.getName().equals("class")) { + continue property; + } + String localizedName = iped.engine.localization.Messages.getString(configurable.getClass().getName() + "." + pd.getDisplayName(), pd.getDisplayName()); + JLabel label = new JLabel(localizedName + ":"); + int width = pd.getDisplayName().length(); + if (max < width) { + max = width; + largestLabel = label; + } + comps.add(label); + if (lastLabel != null) { + layout.putConstraint(SpringLayout.NORTH, label, 15, SpringLayout.SOUTH, lastLabel); + } + + JComponent uiField = createInputForProperty(config, pd); + + layout.putConstraint(SpringLayout.VERTICAL_CENTER, uiField, 0, SpringLayout.VERTICAL_CENTER, label); + comps.add(uiField); + lastLabel = label; + } + } + + public void addCreatedObjects() { + for (Iterator iterator = comps.iterator(); iterator.hasNext();) { + Component component = (Component) iterator.next(); + if (component != largestLabel) { + if (component instanceof JLabel) { + layout.putConstraint(SpringLayout.EAST, component, 0, SpringLayout.EAST, largestLabel); + } else { + layout.putConstraint(SpringLayout.WEST, component, 5, SpringLayout.EAST, largestLabel); + } + } + this.add(component); + } + } + + private JComponent createInputForObject(Object o) { + JComponent uiField = null; + if (o != null) { + if (o instanceof Boolean) { + JCheckBox checkField = new JCheckBox(); + checkField.setText(o.toString()); + checkField.addChangeListener(e -> { + changed = true; + }); + uiField = checkField; + } else { + uiField = createInputForString(o.toString()); + } + } + return uiField; + } + + public JComponent createInputForString(String strConfig) { + boolean isJson = false; + if (strConfig.trim().startsWith("{")) { + JSONParser parser = new JSONParser(); + try { + parser.parse(strConfig); + isJson = true; + } catch (ParseException e) { + } + } + JComponent uiField = null; + + if (isJson) { + RegexTextPane textArea = new RegexTextPane(); + textArea.setAutoscrolls(true); + textArea.setText(strConfig); + textArea.getDocument().addDocumentListener(this); + JScrollPane txtAreaScroll = new JScrollPane(); + txtAreaScroll.setViewportView(textArea); + txtAreaScroll.setAutoscrolls(true); + uiField = txtAreaScroll; + layout.putConstraint(SpringLayout.SOUTH, uiField, 0, SpringLayout.SOUTH, this); + layout.putConstraint(SpringLayout.EAST, uiField, 0, SpringLayout.EAST, this); + } else { + JTextField textField = new JTextField(); + textField.setText(strConfig); + textField.getDocument().addDocumentListener(this); + uiField = textField; + } + return uiField; + } + + public void createObjectGUI(Object o, String strLabel) { + JLabel label = new JLabel(strLabel + ":"); + int width = strLabel.length(); + if (max < width) { + max = width; + largestLabel = label; + } + comps.add(label); + if (lastLabel != null) { + layout.putConstraint(SpringLayout.NORTH, label, 15, SpringLayout.SOUTH, lastLabel); + } + lastLabel = label; + + JComponent uiField = createInputForObject(o); + layout.putConstraint(SpringLayout.NORTH, uiField, 0, SpringLayout.NORTH, label); + comps.add(uiField); + } + + public void createConfigurableGUI() { + try { + lastLabel = null; + comps = new ArrayList(); + largestLabel = null; + max = 0; + + Object config = configurable.getConfiguration(); + if (config != null) { + if (config instanceof Pair) { + createObjectGUI(((Pair) config).getLeft(), "Left"); + createObjectGUI(((Pair) config).getRight(), "Right"); + } else { + createBeanGUI(config); + } + addCreatedObjects(); + } else { + System.out.print("null"); + } + } catch (IllegalArgumentException | IntrospectionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + @Override + public void applyChanges() { + // TODO Auto-generated method stub + + } + +} \ No newline at end of file diff --git a/iped-app/src/main/java/iped/app/home/configurables/popups/CategoryTreePopup.java b/iped-app/src/main/java/iped/app/home/configurables/popups/CategoryTreePopup.java new file mode 100644 index 0000000000..ce31bc65b4 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/popups/CategoryTreePopup.java @@ -0,0 +1,58 @@ +package iped.app.home.configurables.popups; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Iterator; +import java.util.SortedSet; + +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.JTree; + +import iped.app.home.configurables.SetCategoryConfigurablePanel; +import iped.engine.data.Category; + +public class CategoryTreePopup extends JPopupMenu implements ActionListener { + + JMenuItem createCategory; + SetCategoryConfigurablePanel configPanel; + JTree categoryTree; + + public CategoryTreePopup(SetCategoryConfigurablePanel configPanel) { + this.configPanel = configPanel; + this.categoryTree = configPanel.getCategoryTree(); + createCategory = new JMenuItem("Create category"); + createCategory.addActionListener(this); + add(createCategory); + } + + @Override + public void actionPerformed(ActionEvent e) { + if (e.getSource() == createCategory) { + int row = categoryTree.getRowForPath(categoryTree.getLeadSelectionPath()); + // Category cat = (Category) categoryTree.getPathForLocation(this.getX(), + // this.getY()).getLastPathComponent(); + Category cat = (Category) categoryTree.getLeadSelectionPath().getLastPathComponent(); + Category newcat = new Category(); + newcat.setName("New category"); + newcat.setParent(cat); + cat.getChildren().add(newcat); + configPanel.refreshModel(); + + if (row == 0) { + SortedSet children = cat.getChildren(); + int index = 0; + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + Category category = (Category) iterator.next(); + index++; + if (category.equals(newcat)) { + break; + } + } + categoryTree.startEditingAtPath(categoryTree.getPathForRow(index)); + } else { + categoryTree.startEditingAtPath(categoryTree.getPathForRow(row + 1)); + } + } + } +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/popups/ExternalParserPopup.java b/iped-app/src/main/java/iped/app/home/configurables/popups/ExternalParserPopup.java new file mode 100644 index 0000000000..76261d4f98 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/popups/ExternalParserPopup.java @@ -0,0 +1,35 @@ +package iped.app.home.configurables.popups; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.JTree; + +import org.w3c.dom.Document; + +import iped.app.home.configurables.ParsersConfigurablePanel; + +public class ExternalParserPopup extends JPopupMenu implements ActionListener { + JMenuItem createExternalParser; + ParsersConfigurablePanel configPanel; + JTree parsersTree; + Document doc; + + public ExternalParserPopup(ParsersConfigurablePanel configPanel) { + this.configPanel = configPanel; + this.parsersTree = configPanel.getParsersTree(); + this.doc = configPanel.getDocument(); + createExternalParser = new JMenuItem("Create external parser"); + createExternalParser.addActionListener(this); + add(createExternalParser); + } + + @Override + public void actionPerformed(ActionEvent e) { + if (e.getSource() == createExternalParser) { + configPanel.startExternalParserCreation(); + } + } +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/uicomponents/IPEDMimeSearchList.java b/iped-app/src/main/java/iped/app/home/configurables/uicomponents/IPEDMimeSearchList.java new file mode 100644 index 0000000000..582b0bb51b --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/uicomponents/IPEDMimeSearchList.java @@ -0,0 +1,103 @@ +package iped.app.home.configurables.uicomponents; + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.SortedSet; +import java.util.function.Predicate; + +import javax.swing.JCheckBox; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.tika.mime.MediaType; +import org.apache.tika.mime.MediaTypeRegistry; +import org.eclipse.collections.impl.set.sorted.mutable.TreeSortedSet; +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import iped.app.ui.Messages; +import iped.app.ui.controls.IPEDConfigSearchList; +import iped.engine.config.ConfigurationManager; +import iped.engine.config.SignatureConfig; + +public class IPEDMimeSearchList extends IPEDConfigSearchList { + private JCheckBox ckShowTika; + + public IPEDMimeSearchList() { + this(null); + } + + public IPEDMimeSearchList(Predicate availablePredicate) { + super(availablePredicate); + try { + this.availableItems = getAvailableMimetypes(); + } catch (ParserConfigurationException | SAXException | IOException e) { + e.printStackTrace(); + } + createGUI(); + } + + private List getAvailableMimetypes() throws ParserConfigurationException, SAXException, IOException { + SignatureConfig sc = ConfigurationManager.get().findObject(SignatureConfig.class); + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + String xml = sc.getConfiguration(); + ByteArrayInputStream bis = new ByteArrayInputStream(xml.getBytes(Charset.forName("UTF-8"))); + Document doc = docBuilder.parse(bis); + + SortedSet mimes = new TreeSortedSet(); + NodeList nl = doc.getElementsByTagName("mime-type"); + for (int i = 0; i < nl.getLength(); i++) { + String mime = nl.item(i).getAttributes().getNamedItem("type").getNodeValue(); + if (availablePredicate == null || availablePredicate.test(mime)) { + mimes.add(mime); + } + } + + if (ckShowTika != null && ckShowTika.isSelected()) { + SortedSet mts = MediaTypeRegistry.getDefaultRegistry().getTypes(); + for (Iterator iterator = mts.iterator(); iterator.hasNext();) { + MediaType mediaType = (MediaType) iterator.next(); + if (availablePredicate == null || availablePredicate.test(mediaType.toString())) { + mimes.add(mediaType.toString()); + } + } + } + + this.availableItems = new ArrayList(); + this.availableItems.addAll(mimes); + + return this.availableItems; + } + + public void createGUI() { + super.createGUI(new MimeListModel(availableItems, checkTypedContent)); + + ckShowTika = new JCheckBox(); + ckShowTika.setText(Messages.get("Home.IPEDMimeSeachList.showTikaMimeTypes")); + ckShowTika.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + try { + getAvailableMimetypes(); + } catch (ParserConfigurationException | SAXException | IOException e1) { + e1.printStackTrace(); + } + list.setModel(new MimeListModel(availableItems, checkTypedContent)); + } + }); + this.add(ckShowTika, BorderLayout.SOUTH); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/uicomponents/MimeListModel.java b/iped-app/src/main/java/iped/app/home/configurables/uicomponents/MimeListModel.java new file mode 100644 index 0000000000..1708a50173 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/uicomponents/MimeListModel.java @@ -0,0 +1,17 @@ +package iped.app.home.configurables.uicomponents; + +import java.util.List; +import java.util.function.Predicate; + +import iped.app.ui.controls.IPEDFilterableListModel; + +public class MimeListModel extends IPEDFilterableListModel { + + public MimeListModel(List list) { + super(list); + } + + public MimeListModel(List list, Predicate predicate) { + super(list, predicate); + } +} diff --git a/iped-app/src/main/java/iped/app/home/configurables/uicomponents/MimeListTransferHandler.java b/iped-app/src/main/java/iped/app/home/configurables/uicomponents/MimeListTransferHandler.java new file mode 100644 index 0000000000..a7f955af97 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/configurables/uicomponents/MimeListTransferHandler.java @@ -0,0 +1,58 @@ +package iped.app.home.configurables.uicomponents; + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.IOException; + +import javax.swing.JComponent; +import javax.swing.JList; +import javax.swing.TransferHandler; + +public class MimeListTransferHandler extends TransferHandler { + private JList list; + + public MimeListTransferHandler(JList list) { + this.list = list; + } + + public boolean canImport(TransferHandler.TransferSupport info) { + if (!info.isDataFlavorSupported(DataFlavor.stringFlavor)) { + return false; + } + return true; + } + + public int getSourceActions(JComponent c) { + return TransferHandler.MOVE; + } + + public boolean importData(TransferHandler.TransferSupport info) { + if (!info.isDrop()) { + return false; + } + + return true; + } + + @Override + protected Transferable createTransferable(JComponent c) { + return new Transferable() { + public boolean isDataFlavorSupported(DataFlavor flavor) { + return flavor.equals(DataFlavor.stringFlavor); + } + + @Override + public DataFlavor[] getTransferDataFlavors() { + DataFlavor[] dataFlavors = new DataFlavor[1]; + dataFlavors[0] = DataFlavor.stringFlavor; + return dataFlavors; + } + + @Override + public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { + return list.getSelectedValues(); + } + }; + } +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/NewCaseContainerPanel.java b/iped-app/src/main/java/iped/app/home/newcase/NewCaseContainerPanel.java new file mode 100644 index 0000000000..d2930a51ee --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/NewCaseContainerPanel.java @@ -0,0 +1,138 @@ +package iped.app.home.newcase; + +import javax.swing.BoxLayout; +import javax.swing.JTabbedPane; +import javax.swing.plaf.basic.BasicTabbedPaneUI; + +/* + * @created 08/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import iped.app.home.DefaultPanel; +import iped.app.home.MainFrame; +import iped.app.home.MainFrameCardsNames; +import iped.app.home.newcase.model.IPEDProcess; +import iped.app.home.newcase.tabs.caseinfo.CaseInfoTab; +import iped.app.home.newcase.tabs.evidence.EvidencesTab; +import iped.app.home.newcase.tabs.process.ProcessOptionTab; +import iped.app.home.processmanager.ProcessManagerContainer; +import iped.app.ui.Messages; + +/** + * New Case Page here we got the main container for all necessary pages to start + * a new processing + */ +public class NewCaseContainerPanel extends DefaultPanel { + + private JTabbedPane tabbedPane; + private static NewCaseContainerPanel instance; + private IPEDProcess ipedProcess; + private ProcessManagerContainer pmc; + + /** + * Construc and save this instance reference to a static variable + * + * @param mainFrame + * - A reference of MainFrame instance + */ + public NewCaseContainerPanel(MainFrame mainFrame) { + super(mainFrame); + } + + /** + * Prepare everything to be displayed + */ + protected void createAndShowGUI() { + instance = this; + this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); + this.add(setupTabbedPanel()); + } + + /** + * Setup and create a new JTabbedPane instance Here is created a instance of all + * nested JPanels + * + * @return JTabbedPane + */ + private JTabbedPane setupTabbedPanel() { + + tabbedPane = new JTabbedPane(JTabbedPane.LEFT); + // tabbedPane.setEnabled(false); + + tabbedPane.setUI(new BasicTabbedPaneUI() { + @Override + protected int calculateTabHeight(int tabPlacement, int tabIndex, int fontHeight) { + return 45; + } + }); + + tabbedPane.addTab(Messages.get("Home.CaseInformation"), null, new CaseInfoTab(mainFrame), Messages.get("Home.CaseInformationTollTip")); + tabbedPane.addTab(Messages.get("Home.Evidences"), null, new EvidencesTab(mainFrame), Messages.get("Home.EvidencesToolTip")); + tabbedPane.addTab(Messages.get("Home.ProcessOptions"), null, new ProcessOptionTab(mainFrame), Messages.get("Home.ProcessOptionsToolTip")); + pmc = new ProcessManagerContainer(mainFrame); + tabbedPane.addTab(Messages.get("Home.ProcessingTab"), null, pmc, Messages.get("Home.ProcessingTabTooltip")); + disableTabs(); + tabbedPane.setEnabledAt(0, true); + return tabbedPane; + } + + /** + * Display the next Tab available + */ + public void goToNextTab() { + int selectedIndex = tabbedPane.getSelectedIndex(); + boolean isLastTabIndex = (selectedIndex == tabbedPane.getTabCount() - 1); + // if is in the last tab index, prevent to get a invalid index + int nextIndex = isLastTabIndex ? selectedIndex : selectedIndex + 1; + disableTabs(); + tabbedPane.setSelectedIndex(nextIndex); + tabbedPane.setEnabledAt(nextIndex, true); + } + + /** + * Display the previous Tab available + */ + public void goToPreviousTab() { + int selectedIndex = tabbedPane.getSelectedIndex(); + boolean isTheFirstTabIndex = selectedIndex == 0; + int previousIndex = isTheFirstTabIndex ? selectedIndex : selectedIndex - 1; + disableTabs(); + tabbedPane.setSelectedIndex(previousIndex); + tabbedPane.setEnabledAt(previousIndex, true); + } + + private void disableTabs() { + for (int i = 0; i < tabbedPane.getTabCount(); i++) { + tabbedPane.setEnabledAt(i, false); + } + } + + /** + * Go to HomePanel + */ + public void goHome() { + mainFrame.showPanel(MainFrameCardsNames.HOME); + } + + /** + * Return NewCaseContainerPanel instance reference + * + * @return NewCaseContainerPanel - Current NewCaseContainerPanel instance + */ + public static NewCaseContainerPanel getInstance() { + return instance; + } + + public IPEDProcess getIpedProcess() { + if (ipedProcess == null) + ipedProcess = new IPEDProcess(); + return ipedProcess; + } + + public void startIPEDProcessing() { + goToNextTab(); + pmc.startProcess(); + } +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/model/CaseInfo.java b/iped-app/src/main/java/iped/app/home/newcase/model/CaseInfo.java new file mode 100644 index 0000000000..2f01b510fc --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/model/CaseInfo.java @@ -0,0 +1,103 @@ +package iped.app.home.newcase.model; + +/* + * @created 27/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import java.util.ArrayList; + +public class CaseInfo { + + private String caseNumber; + private String caseName; + private ArrayList investigatedNames; + private String requestDate; + private String requester; + private String organizationName; + private ArrayList examiners; + private String contact; + private String caseNotes; + private ArrayList materials; + + public String getCaseNumber() { + return caseNumber; + } + + public void setCaseNumber(String caseNumber) { + this.caseNumber = caseNumber; + } + + public String getCaseName() { + return caseName; + } + + public void setCaseName(String caseName) { + this.caseName = caseName; + } + + public ArrayList getInvestigatedNames() { + return investigatedNames; + } + + public void setInvestigatedNames(ArrayList investigatedNames) { + this.investigatedNames = investigatedNames; + } + + public String getRequestDate() { + return requestDate; + } + + public void setRequestDate(String requestDate) { + this.requestDate = requestDate; + } + + public String getRequester() { + return requester; + } + + public void setRequester(String requester) { + this.requester = requester; + } + + public String getOrganizationName() { + return organizationName; + } + + public void setOrganizationName(String organizationName) { + this.organizationName = organizationName; + } + + public ArrayList getExaminers() { + return examiners; + } + + public void setExaminers(ArrayList examiners) { + this.examiners = examiners; + } + + public String getContact() { + return contact; + } + + public void setContact(String contact) { + this.contact = contact; + } + + public String getCaseNotes() { + return caseNotes; + } + + public void setCaseNotes(String caseNotes) { + this.caseNotes = caseNotes; + } + + public ArrayList getMaterials() { + return materials; + } + + public void setMaterials(ArrayList materials) { + this.materials = materials; + } +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/model/Evidence.java b/iped-app/src/main/java/iped/app/home/newcase/model/Evidence.java new file mode 100644 index 0000000000..81e1671f1b --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/model/Evidence.java @@ -0,0 +1,72 @@ +package iped.app.home.newcase.model;/* + * @created 12/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +public class Evidence implements Cloneable { + + private String fileName; + private String alias; + private String path; + private String timezone; + private String password; + private Integer blocksize; + private String material; + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public String getAlias() { + return alias; + } + + public void setAlias(String alias) { + this.alias = alias; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getTimezone() { + return timezone; + } + + public void setTimezone(String timezone) { + this.timezone = timezone; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public Integer getBlocksize() { + return blocksize; + } + + public void setBlocksize(Integer blocksize) { + this.blocksize = blocksize; + } + + public String getMaterial() { + return material; + } + + public void setMaterial(String material) { + this.material = material; + } +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/model/ExistentCaseOptions.java b/iped-app/src/main/java/iped/app/home/newcase/model/ExistentCaseOptions.java new file mode 100644 index 0000000000..4aa64ceb87 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/model/ExistentCaseOptions.java @@ -0,0 +1,30 @@ +package iped.app.home.newcase.model;/* + * @created 04/01/2023 + * @project IPED + * @author Thiago S. Figueiredo + */ + +public enum ExistentCaseOptions { + APPEND(0, "append"), CONTINUE(1, "continue"), RESTART(2, "restart"); + + private int value; + private String name; + + ExistentCaseOptions(Integer value, String name) { + this.name = name; + this.value = value; + } + + public int getValue() { + return value; + } + + public String getName() { + return name; + } + + public String getCommand() { + return "--".concat(name); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/model/IPEDProcess.java b/iped-app/src/main/java/iped/app/home/newcase/model/IPEDProcess.java new file mode 100644 index 0000000000..f125f9c054 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/model/IPEDProcess.java @@ -0,0 +1,111 @@ +package iped.app.home.newcase.model;/* + * @created 27/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import iped.engine.data.ReportInfo; + +public class IPEDProcess { + + private ReportInfo reportInfo; + private ArrayList evidenceList; + private Path caseOutputPath; + private Map options; + private ExistentCaseOptions existentCaseOption; + private String profile; + private Path asapFile; + + public IPEDProcess() { + evidenceList = new ArrayList<>(); + } + + public ReportInfo getReportInfo() { + return reportInfo; + } + + public void setReportInfo(ReportInfo reportInfo) { + this.reportInfo = reportInfo; + } + + public ArrayList getEvidenceList() { + return evidenceList; + } + + public void setEvidenceList(ArrayList evidenceList) { + this.evidenceList = evidenceList; + } + + public Path getCaseOutputPath() { + return caseOutputPath; + } + + public void setCaseOutputPath(Path caseOutputPath) { + this.caseOutputPath = caseOutputPath; + } + + /** + * A list to of iped command options + * + * @return ArrayList - A list containing the options + */ + private Map getOptions() { + if (options == null) + options = new HashMap() { + }; + return options; + } + + public void setOptions(Map options) { + this.options = options; + } + + public void addOptionValue(String key, String value) { + String currentKey = getOptions().get(key); + if (currentKey == null) { + getOptions().put(key, value); + } else { + getOptions().putIfAbsent(key, value); + } + + } + + public List getOptionsAsList() { + ArrayList optionsList = new ArrayList(); + for (Map.Entry set : getOptions().entrySet()) { + optionsList.add(set.getKey()); + optionsList.add(set.getValue()); + } + return optionsList; + } + + public String getProfile() { + return profile; + } + + public void setProfile(String profile) { + this.profile = profile; + } + + public ExistentCaseOptions getExistentCaseOption() { + return existentCaseOption; + } + + public void setExistentCaseOption(ExistentCaseOptions existentCaseOption) { + this.existentCaseOption = existentCaseOption; + } + + public Path getAsapFile() { + return asapFile; + } + + public void setAsapFile(Path asapFile) { + this.asapFile = asapFile; + } +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/caseinfo/CaseException.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/caseinfo/CaseException.java new file mode 100644 index 0000000000..30ecec2c53 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/caseinfo/CaseException.java @@ -0,0 +1,12 @@ +package iped.app.home.newcase.tabs.caseinfo;/* + * @created 29/12/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +public class CaseException extends Exception { + + public CaseException(String message) { + super(message); + } +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/caseinfo/CaseInfoManager.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/caseinfo/CaseInfoManager.java new file mode 100644 index 0000000000..029878b7d2 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/caseinfo/CaseInfoManager.java @@ -0,0 +1,44 @@ +package iped.app.home.newcase.tabs.caseinfo;/* + * @created 06/12/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +import iped.app.home.newcase.model.Evidence; +import iped.app.ui.Messages; +import iped.engine.core.EvidenceStatus; +import iped.engine.data.ReportInfo; + +public class CaseInfoManager { + + public void validateCasePath(Path casePath) throws CaseException { + if (casePath == null) + throw new CaseException(Messages.get("Home.OpenCase.InavlidCasePath")); + if (!Paths.get(casePath.toString(), "IPED-SearchApp.exe").toFile().exists()) + throw new CaseException(Messages.get("Home.OpenCase.NoSearchApp")); + if (Files.exists(casePath.resolve("indexador/data")) && Files.exists(casePath.resolve("indexador/index"))) + throw new CaseException(Messages.get("Home.OpenCase.CaseV3NotSupported")); + EvidenceStatus status = new EvidenceStatus(casePath.toFile()); + List failedEvidences = status.getFailedEvidences(); + if (failedEvidences == null || !failedEvidences.isEmpty()) + throw new CaseException(Messages.get("Home.OpenCase.CaseNotFinished")); + } + + public void castEvidenceListToReportInfo(ReportInfo reportInfo, ArrayList evidenceList) { + if ((evidenceList == null || evidenceList.isEmpty()) || (reportInfo == null)) + return; + for (Evidence currentEvidence : evidenceList) { + String materialDescription = currentEvidence.getMaterial() != null ? currentEvidence.getMaterial() : currentEvidence.getAlias(); + if (materialDescription == null || materialDescription.isEmpty()) + materialDescription = (currentEvidence.getFileName() == null || currentEvidence.getFileName().isEmpty()) ? "no information.." : currentEvidence.getFileName(); + reportInfo.evidences.add(reportInfo.getEvidenceDescInstance(String.valueOf(evidenceList.indexOf(currentEvidence)), materialDescription)); + } + } + +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/caseinfo/CaseInfoTab.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/caseinfo/CaseInfoTab.java new file mode 100644 index 0000000000..9a70716408 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/caseinfo/CaseInfoTab.java @@ -0,0 +1,585 @@ +package iped.app.home.newcase.tabs.caseinfo;/* + * @created 08/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Image; +import java.awt.Insets; +import java.awt.event.ItemEvent; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.stream.Collectors; + +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.ButtonGroup; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.JScrollPane; +import javax.swing.JSeparator; +import javax.swing.JTextArea; +import javax.swing.JTextField; +import javax.swing.filechooser.FileNameExtensionFilter; +import javax.swing.filechooser.FileSystemView; +import javax.swing.text.JTextComponent; + +import org.apache.commons.lang3.StringUtils; + +import iped.app.home.DefaultPanel; +import iped.app.home.MainFrame; +import iped.app.home.newcase.NewCaseContainerPanel; +import iped.app.home.newcase.model.ExistentCaseOptions; +import iped.app.home.newcase.model.IPEDProcess; +import iped.app.home.style.StyleManager; +import iped.app.home.utils.CasePathManager; +import iped.app.home.utils.JTextAreaTabFocus; +import iped.app.ui.Messages; +import iped.engine.config.ConfigurationManager; +import iped.engine.config.LocalConfig; +import iped.engine.data.ReportInfo; + +/** + * Case info TAB + */ +public class CaseInfoTab extends DefaultPanel { + + private LocalConfig localConfig; + private IPEDProcess ipedProcess; + + private JTextField textFieldCaseOutput; + private JCheckBox checkBoxOutputOnSSD; + private JButton buttonSelectCaseOutput; + private JButton buttonCheckCaseOutput; + private JTextField textFieldReportNumber; + private JTextField textFieldReportDate; + private JTextField textFieldReportTitle; + private JTextArea textAreaInvestigatedNames; + private JTextField textFieldRequestDate; + private JTextField textFieldCaseNumber; + private JTextField textFieldLabCaseNumber; + private JTextField textFieldLabCaseDate; + private JTextField textFieldRequestForm; + private JTextField textFieldRequester; + private JTextField textFieldOrganization; + private JTextArea textAreaExaminerNames; + private JTextField textFieldContact; + private JTextArea textAreaCaseNotes; + private JPanel panelCaseOutputOptions; + private JRadioButton radioCaseOutAdd; + private JRadioButton radioCaseOutContinue; + private JRadioButton radioCaseOutRestart; + private ButtonGroup buttonGroupCaseOutOptions; + private FileNameExtensionFilter jsonFilter = new FileNameExtensionFilter("caseinfo.json", new String[] { "json", "JSON" }); + private ArrayList caseInfoInputList; + + public CaseInfoTab(MainFrame mainFrame) { + super(mainFrame); + } + + /** + * Prepare everything to be displayed + */ + protected void createAndShowGUI() { + ipedProcess = NewCaseContainerPanel.getInstance().getIpedProcess(); + this.setLayout(new BorderLayout()); + this.add(createTitlePanel(), BorderLayout.NORTH); + this.add(createFormPanel(), BorderLayout.CENTER); + this.add(createNavigationButtonsPanel(), BorderLayout.SOUTH); + } + + /** + * Create a new JPanel instance containing the Page Title + * + * @return - JPanel containing the Page Title + */ + private JPanel createTitlePanel() { + JPanel panelTitle = new JPanel(); + panelTitle.setBackground(Color.white); + JLabel labelTitle = new JLabel(Messages.get("Home.CaseInformation")); + labelTitle.setFont(StyleManager.getPageTitleFont()); + panelTitle.add(labelTitle); + return panelTitle; + } + + private void createFormComponentInstances() { + localConfig = ConfigurationManager.get().findObject(LocalConfig.class); + caseInfoInputList = new ArrayList<>(); + + textFieldReportNumber = new JTextField(); + caseInfoInputList.add(textFieldReportNumber); + textFieldReportDate = new JTextField(); + caseInfoInputList.add(textFieldReportDate); + textFieldReportTitle = new JTextField(); + caseInfoInputList.add(textFieldReportTitle); + JTextAreaTabFocus tabFocus = new JTextAreaTabFocus(); + textAreaInvestigatedNames = new JTextArea(); + caseInfoInputList.add(textAreaInvestigatedNames); + textAreaInvestigatedNames.addKeyListener(tabFocus); + textAreaInvestigatedNames.setBorder(BorderFactory.createLineBorder(Color.gray)); + textAreaInvestigatedNames.setLineWrap(true); + textAreaInvestigatedNames.setWrapStyleWord(true); + textFieldRequestDate = new JTextField(); + caseInfoInputList.add(textFieldRequestDate); + textFieldCaseNumber = new JTextField(); + caseInfoInputList.add(textFieldCaseNumber); + textFieldRequestForm = new JTextField(); + caseInfoInputList.add(textFieldRequestForm); + textFieldRequester = new JTextField(); + caseInfoInputList.add(textFieldRequester); + textFieldLabCaseNumber = new JTextField(); + caseInfoInputList.add(textFieldLabCaseNumber); + textFieldLabCaseDate = new JTextField(); + caseInfoInputList.add(textFieldLabCaseDate); + textFieldOrganization = new JTextField(); + caseInfoInputList.add(textFieldOrganization); + textAreaExaminerNames = new JTextArea(); + caseInfoInputList.add(textAreaExaminerNames); + textAreaExaminerNames.setBorder(BorderFactory.createLineBorder(Color.gray)); + textAreaExaminerNames.addKeyListener(tabFocus); + textAreaExaminerNames.setLineWrap(true); + textAreaExaminerNames.setWrapStyleWord(true); + textFieldContact = new JTextField(); + caseInfoInputList.add(textFieldContact); + textAreaCaseNotes = new JTextArea(); + caseInfoInputList.add(textAreaCaseNotes); + textAreaCaseNotes.setBorder(BorderFactory.createLineBorder(Color.gray)); + textAreaCaseNotes.setRows(5); + textAreaCaseNotes.addKeyListener(tabFocus); + textAreaCaseNotes.setLineWrap(true); + textAreaCaseNotes.setWrapStyleWord(true); + + textFieldCaseOutput = new JTextField(); + textFieldCaseOutput.setEditable(false); + checkBoxOutputOnSSD = new JCheckBox(Messages.get("Home.NewCase.IsCaseOutputOnSSD")); + checkBoxOutputOnSSD.setToolTipText(Messages.get("Home.NewCase.IsCaseOutputOnSSDToolTip")); + checkBoxOutputOnSSD.setSelected(localConfig.isOutputOnSSD()); + checkBoxOutputOnSSD.setOpaque(false); + checkBoxOutputOnSSD.addItemListener(e -> { + try { + Boolean isEnableOutputSSD = (e.getStateChange() == ItemEvent.SELECTED); + LocalConfig localConfig = ConfigurationManager.get().findObject(LocalConfig.class); + localConfig.getPropertie().setProperty(LocalConfig.OUTPUT_ON_SSD, isEnableOutputSSD.toString()); + localConfig.getPropertie().saveOnFile(CasePathManager.getInstance().getLocalConfigFile()); + ConfigurationManager.get().reloadConfigurable(LocalConfig.class); + } catch (IOException ex) { + ex.printStackTrace(); + } + }); + buttonSelectCaseOutput = new JButton("..."); + buttonSelectCaseOutput.addActionListener(e -> { + JFileChooser fileChooserDestino = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory()); + fileChooserDestino.setDialogTitle(Messages.get("Home.NewCase.ChooseCaseOutput")); + fileChooserDestino.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + fileChooserDestino.setAcceptAllFileFilterUsed(false); + String outputStr = textFieldCaseOutput.getText(); + if (!outputStr.isBlank()) { + fileChooserDestino.setCurrentDirectory(new File(outputStr)); + } + if (fileChooserDestino.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { + setCaseOutputValue(fileChooserDestino.getSelectedFile().toPath()); + } + }); + buttonCheckCaseOutput = new JButton(""); + Image img = (new ImageIcon(getClass().getResource("/iped/app/ui/refresh.png"))).getImage(); + Image resizedIcon = img.getScaledInstance(15, 15, java.awt.Image.SCALE_SMOOTH); + buttonCheckCaseOutput.setIcon(new ImageIcon(resizedIcon)); + buttonCheckCaseOutput.addActionListener(e -> { + if (ipedProcess.getCaseOutputPath() != null) + setCaseOutputValue(ipedProcess.getCaseOutputPath()); + + }); + } + + private File showSaveCaseInfoFileChooser(String title) { + JFileChooser fileChooser = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory()); + fileChooser.setDialogTitle(title); + fileChooser.setAcceptAllFileFilterUsed(false); + fileChooser.addChoosableFileFilter(jsonFilter); + int returnValue = fileChooser.showSaveDialog(this); + if (returnValue == JFileChooser.APPROVE_OPTION) { + File file = fileChooser.getSelectedFile(); + if (!file.getName().toLowerCase().endsWith(".json")) { + file = new File(file.getParentFile(), file.getName() + ".json"); + } + return file; + } + return null; + } + + private File showLoadCaseInfoFileChooser(String title) { + JFileChooser fileChooser = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory()); + fileChooser.setDialogTitle(title); + fileChooser.setAcceptAllFileFilterUsed(false); + fileChooser.addChoosableFileFilter(jsonFilter); + int returnValue = fileChooser.showOpenDialog(this); + if (returnValue == JFileChooser.APPROVE_OPTION) { + return fileChooser.getSelectedFile(); + } + return null; + } + + private void setCaseOutputValue(Path caseOutput) { + // first check if exists a case on selected output folder + boolean isExistsCase = Paths.get(caseOutput.toString(), "IPED-SearchApp.exe").toFile().exists(); + panelCaseOutputOptions.setVisible(isExistsCase); + if (isExistsCase) { + // check if the existent case is finished, if yes the user cannot choose the + // continue options + boolean isCaseFinished = Paths.get(caseOutput.toString(), "iped", "data", "processing_finished").toFile().exists(); + radioCaseOutContinue.setVisible(!isCaseFinished); + } + // when user reselect other path wee need to unselect the previously selected + // radio button + if (!panelCaseOutputOptions.isVisible()) { + ipedProcess.setExistentCaseOption(null); + buttonGroupCaseOutOptions.clearSelection(); + } + + IPEDProcess ipedProcess = NewCaseContainerPanel.getInstance().getIpedProcess(); + ipedProcess.setCaseOutputPath(caseOutput); + textFieldCaseOutput.setText(caseOutput.toString()); + } + + /** + * Create a new JPanel instance containing all inputs + * + * @return JPanel - A JPanel containing all data input form itens + */ + private JScrollPane createFormPanel() { + JPanel panelForm = new JPanel(new GridBagLayout()); + panelForm.setBackground(super.getCurrentBackGroundColor()); + createFormComponentInstances(); + + int column0 = 0; + int column1 = 1; + + int column0Width = 1; + int column1width = 2; + int fullColumnWidth = column0Width + column1width; + + double noWeightx = 0; + double fullWeightx = 1.0; + + int currentLine = 0; + + panelForm.add(new JLabel(Messages.get("ReportDialog.ReportNum") + ":"), getGridBagConstraints(column0, currentLine, column0Width, noWeightx)); + panelForm.add(textFieldReportNumber, getGridBagConstraints(column1, currentLine++, column1width, fullWeightx)); + + panelForm.add(new JLabel(Messages.get("ReportDialog.ReportDate") + ":"), getGridBagConstraints(column0, currentLine, column0Width, noWeightx)); + panelForm.add(textFieldReportDate, getGridBagConstraints(column1, currentLine++, column1width, fullWeightx)); + + panelForm.add(new JLabel(Messages.get("ReportDialog.ReportTitle") + ":"), getGridBagConstraints(column0, currentLine, column0Width, noWeightx)); + panelForm.add(textFieldReportTitle, getGridBagConstraints(column1, currentLine++, column1width, fullWeightx)); + + panelForm.add(new JLabel(Messages.get("ReportDialog.Examiner") + ":"), getGridBagConstraints(column0, currentLine, column0Width, noWeightx)); + panelForm.add(textAreaExaminerNames, getGridBagConstraints(column1, currentLine++, column1width, fullWeightx)); + + panelForm.add(new JLabel(Messages.get("ReportDialog.Investigation") + ":"), getGridBagConstraints(column0, currentLine, column0Width, noWeightx)); + panelForm.add(textFieldCaseNumber, getGridBagConstraints(column1, currentLine++, column1width, fullWeightx)); + + panelForm.add(new JLabel(Messages.get("ReportDialog.Request") + ":"), getGridBagConstraints(column0, currentLine, column0Width, noWeightx)); + panelForm.add(textFieldRequestForm, getGridBagConstraints(column1, currentLine++, column1width, fullWeightx)); + + panelForm.add(new JLabel(Messages.get("ReportDialog.RequestDate") + ":"), getGridBagConstraints(column0, currentLine, column0Width, noWeightx)); + panelForm.add(textFieldRequestDate, getGridBagConstraints(column1, currentLine++, column1width, fullWeightx)); + + panelForm.add(new JLabel(Messages.get("ReportDialog.Requester") + ":"), getGridBagConstraints(column0, currentLine, column0Width, noWeightx)); + panelForm.add(textFieldRequester, getGridBagConstraints(column1, currentLine++, column1width, fullWeightx)); + + panelForm.add(new JLabel(Messages.get("ReportDialog.Record") + ":"), getGridBagConstraints(column0, currentLine, column0Width, noWeightx)); + panelForm.add(textFieldLabCaseNumber, getGridBagConstraints(column1, currentLine++, column1width, fullWeightx)); + + panelForm.add(new JLabel(Messages.get("ReportDialog.RecordDate") + ":"), getGridBagConstraints(column0, currentLine, column0Width, noWeightx)); + panelForm.add(textFieldLabCaseDate, getGridBagConstraints(column1, currentLine++, column1width, fullWeightx)); + + panelForm.add(new JLabel(Messages.get("ReportDialog.InvestigatedNames") + ":"), getGridBagConstraints(column0, currentLine, column0Width, noWeightx)); + panelForm.add(textAreaInvestigatedNames, getGridBagConstraints(column1, currentLine++, column1width, fullWeightx)); + + panelForm.add(new JLabel(Messages.get("ReportDialog.organizationName") + ":"), getGridBagConstraints(column0, currentLine, column0Width, noWeightx)); + panelForm.add(textFieldOrganization, getGridBagConstraints(column1, currentLine++, column1width, fullWeightx)); + + panelForm.add(new JLabel(Messages.get("ReportDialog.contact") + ":"), getGridBagConstraints(column0, currentLine, column0Width, noWeightx)); + panelForm.add(textFieldContact, getGridBagConstraints(column1, currentLine++, column1width, fullWeightx)); + + panelForm.add(new JLabel(Messages.get("ReportDialog.caseNotes") + ":"), getGridBagConstraints(column0, currentLine, column0Width, noWeightx)); + panelForm.add(textAreaCaseNotes, getGridBagConstraints(column1, currentLine++, column1width, fullWeightx)); + + // ----------------Case data buttons----------------- + panelForm.add(createCaseDataPanel(), getGridBagConstraints(column0, currentLine++, fullColumnWidth, fullWeightx, new Insets(10, 10, 0, 10))); + + // ----------------Line Separator----------------- + panelForm.add(new JSeparator(), getGridBagConstraints(column0, currentLine++, fullColumnWidth, fullWeightx, new Insets(10, 10, 10, 10))); + + panelForm.add(new JLabel(Messages.get("Home.NewCase.CaseOutput") + ":"), getGridBagConstraints(column0, currentLine, column0Width, noWeightx)); + panelForm.add(createSetCaseOutputPanel(), getGridBagConstraints(column1, currentLine++, column1width, fullWeightx)); + + panelForm.add(checkBoxOutputOnSSD, getGridBagConstraints(column1, currentLine++, column1width, fullWeightx)); + + panelCaseOutputOptions = createCaseOutputOptionsPanel(); + panelForm.add(panelCaseOutputOptions, getGridBagConstraints(column0, currentLine, fullColumnWidth, fullWeightx, new Insets(10, 10, 0, 10))); + + return new JScrollPane(panelForm); + + } + + /** + * Create a JPanel with one textfield and a button to set the case output + * + * @return JPanel with a textfield and a button to set case output + */ + private JPanel createSetCaseOutputPanel() { + JPanel panelCaseOutput = new JPanel(); + panelCaseOutput.setLayout(new BoxLayout(panelCaseOutput, BoxLayout.LINE_AXIS)); + panelCaseOutput.setBackground(Color.white); + panelCaseOutput.add(textFieldCaseOutput); + panelCaseOutput.add(buttonSelectCaseOutput); + panelCaseOutput.add(buttonCheckCaseOutput); + return panelCaseOutput; + } + + private JPanel createCaseOutputOptionsPanel() { + buttonGroupCaseOutOptions = new ButtonGroup(); + radioCaseOutAdd = new JRadioButton(Messages.get("Home.AppendExistentCase"), false); + radioCaseOutAdd.setBackground(super.getCurrentBackGroundColor()); + radioCaseOutContinue = new JRadioButton(Messages.get("Home.ContinueExistentCase"), false); + radioCaseOutContinue.setBackground(super.getCurrentBackGroundColor()); + radioCaseOutRestart = new JRadioButton(Messages.get("Home.RestartExistentCase"), false); + radioCaseOutRestart.setBackground(super.getCurrentBackGroundColor()); + buttonGroupCaseOutOptions.add(radioCaseOutAdd); + buttonGroupCaseOutOptions.add(radioCaseOutContinue); + buttonGroupCaseOutOptions.add(radioCaseOutRestart); + + JPanel panel = new JPanel(); + panel.setVisible(false); + panel.setBackground(super.getCurrentBackGroundColor()); + panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS)); + JLabel labelCaseOptionMessage = new JLabel(Messages.get("Home.ExistentCaseAlert")); + labelCaseOptionMessage.setForeground(Color.RED); + panel.add(labelCaseOptionMessage); + panel.add(radioCaseOutAdd); + panel.add(radioCaseOutContinue); + panel.add(radioCaseOutRestart); + return panel; + } + + /** + * Create a JPanel with Save and load buttons + * + * @return A new JPanel with Case Button + */ + private JPanel createCaseDataPanel() { + JPanel panelCaseData = new JPanel(); + panelCaseData.setBackground(super.getCurrentBackGroundColor()); + JButton buttonSaveCaseData = new JButton(Messages.get("Home.NewCase.SaveCaseData")); + buttonSaveCaseData.addActionListener(e -> { + File destinationFile = showSaveCaseInfoFileChooser(Messages.get("Home.NewCase.ChooseCaseInfoFileOutput")); + if (destinationFile != null) { + populateCaseInfo(); + ipedProcess.getReportInfo().saveJsonInfoFile(destinationFile); + } + }); + JButton buttonLoadCaseData = new JButton(Messages.get("Home.NewCase.LoadCaseData")); + buttonLoadCaseData.addActionListener(e -> { + if (isCaseInfoFormFilled()) { + int selectedOption = JOptionPane.showConfirmDialog(null, Messages.get("Home.NewCase.OpenCaseFileDialogMessage"), Messages.get("Home.NewCase.OpenCaseFileDialogTitle"), JOptionPane.YES_NO_OPTION); + if (selectedOption == 1) + return; + } + + File caseInfoSourceFile = showLoadCaseInfoFileChooser(Messages.get("Home.NewCase.ChooseCaseInfoFile")); + if (caseInfoSourceFile != null) { + ReportInfo reportInfo = new ReportInfo(); + try { + reportInfo.readJsonInfoFile(caseInfoSourceFile); + } catch (IOException ex) { + ex.printStackTrace(); + return; + } + ipedProcess.setReportInfo(reportInfo); + populateFormCaseInfo(); + } + }); + panelCaseData.add(buttonSaveCaseData); + panelCaseData.add(buttonLoadCaseData); + return panelCaseData; + } + + /** + * Create a new GridBagConstraints to be used on this page Form + * + * @param tableColumnIndex + * - The index number of table column + * @param tableLineIndex + * - The index number of table line + * @param cellWidth + * - The table Cell Width + * @param weightX + * - Cell Weight X + * @return GridBagConstraints - a new GridBagConstraints instance containing all + * parameter passed + */ + private GridBagConstraints getGridBagConstraints(int tableColumnIndex, int tableLineIndex, int cellWidth, double weightX) { + GridBagConstraints gbcons = new GridBagConstraints(); + gbcons.fill = GridBagConstraints.HORIZONTAL; + gbcons.weightx = weightX; + gbcons.gridx = tableColumnIndex; + gbcons.gridy = tableLineIndex; + gbcons.gridwidth = cellWidth; + gbcons.gridheight = 1; + gbcons.insets = new Insets(2, 10, 2, 10); + return gbcons; + } + + /** + * Create a new GridBagConstraints to be used on this page Form + * + * @param tableColumnIndex + * - The index number of table column + * @param tableLineIndex + * - The index number of table line + * @param cellWidth + * - The table Cell Width + * @param weightX + * - Cell Weight X + * @param insets + * - the Insets + * @return GridBagConstraints - a new GridBagConstraints instance containing all + * parameter passed + */ + private GridBagConstraints getGridBagConstraints(int tableColumnIndex, int tableLineIndex, int cellWidth, double weightX, Insets insets) { + GridBagConstraints gbcons = getGridBagConstraints(tableColumnIndex, tableLineIndex, cellWidth, weightX); + gbcons.insets = insets; + return gbcons; + } + + /** + * A JPanel containing "Cancel" and "Next" buttons + * + * @return JPanel - a new JPanel instance containing the bottom page Button + */ + private JPanel createNavigationButtonsPanel() { + JPanel panelButtons = new JPanel(); + panelButtons.setBackground(Color.white); + JButton buttoCancel = new JButton(Messages.get("Home.Cancel")); + buttoCancel.addActionListener(e -> NewCaseContainerPanel.getInstance().goHome()); + JButton buttonNext = new JButton(Messages.get("Home.Next")); + buttonNext.addActionListener(e -> navigateToNextTab()); + panelButtons.add(buttoCancel); + panelButtons.add(buttonNext); + return panelButtons; + } + + private void navigateToNextTab() { + Path casePath = ipedProcess.getCaseOutputPath(); + // check if output path exists + if ((casePath == null) || (!Files.isDirectory(casePath))) { + JOptionPane.showMessageDialog(this, Messages.get("Home.NewCase.CaseOutputRequired"), Messages.get("Home.NewCase.CaseOutputRequiredTitle"), JOptionPane.WARNING_MESSAGE); + return; + } + // Check case output permissions + if ((!Files.isReadable(casePath)) || (!Files.isWritable(casePath))) { + JOptionPane.showMessageDialog(this, Messages.get("Home.NewCase.CaseOutputPermission"), Messages.get("Home.NewCase.CaseOutputPermissionTitle"), JOptionPane.WARNING_MESSAGE); + return; + } + if (panelCaseOutputOptions.isVisible() && (buttonGroupCaseOutOptions.getSelection() == null)) { + JOptionPane.showMessageDialog(this, Messages.get("Home.NewCase.CaseOutPutOptionsRequired"), Messages.get("Home.NewCase.CaseOutputRequiredTitle"), JOptionPane.WARNING_MESSAGE); + return; + } + + setCaseOutputOptions(); + populateCaseInfo(); + NewCaseContainerPanel.getInstance().goToNextTab(); + } + + private void setCaseOutputOptions() { + if (radioCaseOutAdd.isSelected()) + ipedProcess.setExistentCaseOption(ExistentCaseOptions.APPEND); + if (radioCaseOutContinue.isSelected()) + ipedProcess.setExistentCaseOption(ExistentCaseOptions.CONTINUE); + if (radioCaseOutRestart.isSelected()) + ipedProcess.setExistentCaseOption(ExistentCaseOptions.RESTART); + } + + private void populateCaseInfo() { + ReportInfo reportInfo = ipedProcess.getReportInfo(); + if (reportInfo == null) { + reportInfo = new ReportInfo(); + ipedProcess.setReportInfo(reportInfo); + } + reportInfo.reportNumber = textFieldReportNumber.getText(); + reportInfo.reportDate = textFieldReportDate.getText(); + reportInfo.reportTitle = textFieldReportTitle.getText(); + reportInfo.examiners = new ArrayList<>(Arrays.asList(textAreaExaminerNames.getText().split("\n"))); + reportInfo.caseNumber = textFieldCaseNumber.getText(); + reportInfo.requestForm = textFieldRequestForm.getText(); + reportInfo.requestDate = textFieldRequestDate.getText(); + reportInfo.requester = textFieldRequester.getText(); + reportInfo.labCaseNumber = textFieldLabCaseNumber.getText(); + reportInfo.labCaseDate = textFieldLabCaseDate.getText(); + reportInfo.investigatedName = new ArrayList<>(Arrays.asList(textAreaInvestigatedNames.getText().split("\n"))); + reportInfo.organizationName = textFieldOrganization.getText(); + reportInfo.contact = textFieldContact.getText(); + reportInfo.caseNotes = textAreaCaseNotes.getText(); + reportInfo.evidences = new ArrayList<>(); + } + + /** + * Check if there is any information filled in case info form + * + * @return + */ + private boolean isCaseInfoFormFilled() { + for (JTextComponent currentCaseInfoInput : caseInfoInputList) { + if (!StringUtils.isEmpty(currentCaseInfoInput.getText())) + return true; + } + return false; + } + + /** + * Fill the form inputs with reportinfo class data + */ + private void populateFormCaseInfo() { + String emptyValue = ""; + ReportInfo reportInfo = ipedProcess.getReportInfo(); + textFieldReportNumber.setText(reportInfo.reportNumber != null ? reportInfo.reportNumber : emptyValue); + textFieldReportDate.setText(reportInfo.reportDate != null ? reportInfo.reportDate : emptyValue); + textFieldReportTitle.setText(reportInfo.reportTitle != null ? reportInfo.reportTitle : emptyValue); + if ((reportInfo.examiners != null) && (!reportInfo.examiners.isEmpty())) { + String examinerNames = reportInfo.examiners.stream().map(String::trim).collect(Collectors.joining("\n")); + textAreaExaminerNames.append(examinerNames); + } else + textAreaExaminerNames.setText(emptyValue); + textFieldCaseNumber.setText(reportInfo.caseNumber != null ? reportInfo.caseNumber : emptyValue); + textFieldRequestForm.setText(reportInfo.requestForm != null ? reportInfo.requestForm : emptyValue); + textFieldRequestDate.setText(reportInfo.requestDate != null ? reportInfo.requestDate : emptyValue); + textFieldRequester.setText(reportInfo.requester != null ? reportInfo.requester : emptyValue); + textFieldLabCaseNumber.setText(reportInfo.labCaseNumber != null ? reportInfo.labCaseNumber : emptyValue); + textFieldLabCaseDate.setText(reportInfo.labCaseDate != null ? reportInfo.labCaseDate : emptyValue); + if ((reportInfo.investigatedName != null) && (!reportInfo.investigatedName.isEmpty())) { + String investigatedNames = reportInfo.investigatedName.stream().map(String::trim).collect(Collectors.joining("\n")); + textAreaInvestigatedNames.setText(investigatedNames); + } else + textAreaInvestigatedNames.setText(emptyValue); + textFieldOrganization.setText(reportInfo.organizationName != null ? reportInfo.organizationName : emptyValue); + textFieldContact.setText(reportInfo.contact != null ? reportInfo.contact : emptyValue); + textAreaCaseNotes.setText(reportInfo.caseNotes != null ? reportInfo.caseNotes : emptyValue); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/DiskSelecionDialog.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/DiskSelecionDialog.java new file mode 100644 index 0000000000..34155c8fe6 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/DiskSelecionDialog.java @@ -0,0 +1,93 @@ +package iped.app.home.newcase.tabs.evidence;/* + * @created 10/12/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import java.awt.Frame; +import java.awt.Insets; +import java.util.ArrayList; + +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; + +import iped.app.home.newcase.model.Evidence; +import iped.app.home.style.StyleManager; +import iped.app.ui.Messages; +import iped.utils.ProcessUtil; +import oshi.hardware.HWDiskStore; + +public class DiskSelecionDialog extends JDialog { + + private ArrayList evidenceListListener = new ArrayList<>(); + private JDialog diskDialog; + private JButton okButton = new JButton(Messages.get("Home.Evidences.DisksDialog.Select")); + private JTable tableDiskSelection; + private DisksTableModel tableModel; + private ArrayList evidencesList; + + public DiskSelecionDialog(Frame owner, ArrayList evidencesList) { + super(owner); + this.evidencesList = evidencesList; + diskDialog = this; + + diskDialog.setTitle(Messages.get("Home.Evidences.DisksDialog.Title")); //$NON-NLS-1$ + diskDialog.setBounds(0, 0, 1024, 400); + diskDialog.setLocationRelativeTo(null); + + JPanel mainPanel = new JPanel(); + mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS)); + Insets inset = StyleManager.getDefaultPanelInsets(); + mainPanel.setBorder(BorderFactory.createEmptyBorder(inset.top, inset.left, inset.bottom, inset.right)); + + tableModel = new DisksTableModel(evidencesList); + tableDiskSelection = new JTable(tableModel); + tableDiskSelection.setFillsViewportHeight(true); + tableDiskSelection.setRowHeight(30); + + JScrollPane scroll = new JScrollPane(); + scroll.setViewportView(tableDiskSelection); + mainPanel.add(scroll); + + JPanel buttonPanel = new JPanel(); + buttonPanel.add(okButton); + mainPanel.add(buttonPanel); + + diskDialog.getContentPane().add(mainPanel); + + okButton.addActionListener(e -> { + if (ProcessUtil.isRunningAsAdmin()) { + addDiskToEvidenceList(); + } else { + JOptionPane.showMessageDialog(this, Messages.get("Home.Evidences.DisksDialog.NotAdmin"), "Error", JOptionPane.ERROR_MESSAGE); + } + this.setVisible(false); + }); + } + + private void addDiskToEvidenceList() { + for (int rowIndex : tableDiskSelection.getSelectedRows()) { + HWDiskStore disk = ((DisksTableModel) tableDiskSelection.getModel()).getDiskAt(rowIndex); + Evidence evidence = new Evidence(); + evidence.setFileName(disk.getModel()); + evidence.setPath(disk.getName()); + evidencesList.add(evidence); + } + evidenceListListener.forEach(e -> e.evidenceDataChange()); + } + + public void showDialog() { + this.setVisible(true); + } + + public void addListener(EvidenceListListener listener) { + evidenceListListener.add(listener); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/DisksTableModel.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/DisksTableModel.java new file mode 100644 index 0000000000..2ae993654f --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/DisksTableModel.java @@ -0,0 +1,81 @@ +package iped.app.home.newcase.tabs.evidence;/* + * @created 11/12/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import java.util.ArrayList; +import java.util.List; + +import javax.swing.table.AbstractTableModel; + +import iped.app.home.newcase.model.Evidence; +import iped.app.ui.Messages; +import oshi.SystemInfo; +import oshi.hardware.HWDiskStore; +import oshi.hardware.HardwareAbstractionLayer; + +public class DisksTableModel extends AbstractTableModel { + + private final String[] COLUMN_NAME = { Messages.get("Home.Evidences.DisksDialog.Name"), Messages.get("Home.Evidences.DisksDialog.Model"), Messages.get("Home.Evidences.DisksDialog.Size"), + Messages.get("Home.Evidences.DisksDialog.Serial") }; + private final ArrayList evidencesList; + private final List disksList; + + public DisksTableModel(ArrayList evidencesList) { + this.evidencesList = evidencesList; + SystemInfo si = new SystemInfo(); + HardwareAbstractionLayer hal = si.getHardware(); + disksList = hal.getDiskStores(); + } + + @Override + public int getRowCount() { + return (disksList != null) ? disksList.size() : 0; + } + + @Override + public int getColumnCount() { + return COLUMN_NAME.length; + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + if (disksList == null) + return ""; + switch (columnIndex) { + case 0: + return disksList.get(rowIndex).getName(); + case 1: + return disksList.get(rowIndex).getModel(); + case 2: + return getDiskSize(disksList.get(rowIndex).getSize()); + case 3: + return disksList.get(rowIndex).getSerial(); + default: + return ""; + } + } + + public HWDiskStore getDiskAt(int rowIndex) { + return disksList.get(rowIndex); + } + + private String getDiskSize(long v) { + if (v < 1024) + return v + " B"; + int z = (63 - Long.numberOfLeadingZeros(v)) / 10; + return String.format("%.1f %sB", (double) v / (1L << (z * 10)), " KMGTPE".charAt(z)); + } + + @Override + public boolean isCellEditable(int rowIndex, int columnIndex) { + return false; + } + + @Override + public String getColumnName(int column) { + return COLUMN_NAME[column]; + } + +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/EvidenceInfoDialog.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/EvidenceInfoDialog.java new file mode 100644 index 0000000000..d9dbd1c8dc --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/EvidenceInfoDialog.java @@ -0,0 +1,148 @@ +package iped.app.home.newcase.tabs.evidence;/* + * @created 27/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.util.ArrayList; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.JTextField; + +import iped.app.home.newcase.model.Evidence; +import iped.app.home.style.StyleManager; +import iped.app.ui.Messages; + +public class EvidenceInfoDialog extends JDialog { + + private Evidence evidence; + private ArrayList evidenceListListener = new ArrayList<>(); + + private JDialog evidenceDialog; + private JButton okButton = new JButton("OK"); + private JLabel labelFileName = new JLabel(); + private JLabel labelPath = new JLabel(); + private JTextField textFieldAlias = new JTextField(); + private JTextField textFieldPassword = new JTextField(); + private JTextField textFieldTimeZone = new JTextField(); + private JTextField textFieldBlocksize = new JTextField(); + private JTextArea textAreaMaterial = new JTextArea(); + + public EvidenceInfoDialog(Frame owner) { + super(owner); + evidenceDialog = this; + + evidenceDialog.setTitle(Messages.get("Home.Evidences.DialogTitle")); //$NON-NLS-1$ + evidenceDialog.setBounds(0, 0, 1024, 400); + evidenceDialog.setLocationRelativeTo(null); + + JPanel fullPanel = new JPanel(new BorderLayout()); + Insets inset = StyleManager.getDefaultPanelInsets(); + fullPanel.setBorder(BorderFactory.createEmptyBorder(inset.top, inset.left, inset.bottom, inset.right)); + + JPanel panel = new JPanel(new GridBagLayout()); + + int line = 0; + JLabel filename = new JLabel(Messages.get("Home.Evidences.Dialog.FileName")); + panel.add(filename, getGridBagConstraints(0, line, 1, 1)); + panel.add(labelFileName, getGridBagConstraints(1, line, 2, 1)); + + line++; + panel.add(new JLabel(Messages.get("Home.Evidences.Dialog.Path")), getGridBagConstraints(0, line, 1, 1)); + panel.add(labelPath, getGridBagConstraints(1, line, 2, 1)); + + line++; + panel.add(new JLabel(Messages.get("Home.Evidences.Dialog.Alias")), getGridBagConstraints(0, line, 1, 1)); + panel.add(textFieldAlias, getGridBagConstraints(1, line, 2, 1)); + + line++; + panel.add(new JLabel(Messages.get("Home.Evidences.Dialog.EvidenceDesc")), getGridBagConstraints(0, line, 1, 1)); + textAreaMaterial.setBorder(BorderFactory.createLineBorder(Color.BLACK)); + textAreaMaterial.setRows(3); + panel.add(textAreaMaterial, getGridBagConstraints(1, line, 2, 1)); + + line++; + panel.add(new JLabel(Messages.get("Home.Evidences.Dialog.Password")), getGridBagConstraints(0, line, 1, 1)); + panel.add(textFieldPassword, getGridBagConstraints(1, line, 2, 1)); + + line++; + panel.add(new JLabel(Messages.get("Home.Evidences.Dialog.TimeZone")), getGridBagConstraints(0, line, 1, 1)); + panel.add(textFieldTimeZone, getGridBagConstraints(1, line, 2, 1)); + + line++; + panel.add(new JLabel(Messages.get("Home.Evidences.Dialog.BlockSize")), getGridBagConstraints(0, line, 1, 1)); + panel.add(textFieldBlocksize, getGridBagConstraints(1, line, 2, 1)); + + fullPanel.add(panel, BorderLayout.CENTER); + JPanel bPanel = new JPanel(); + bPanel.add(okButton); + fullPanel.add(bPanel, BorderLayout.SOUTH); + + evidenceDialog.getContentPane().add(new JScrollPane(fullPanel)); + + okButton.addActionListener(e -> { + saveData(); + this.setVisible(false); + }); + } + + private GridBagConstraints getGridBagConstraints(int x, int y, int width, int height) { + GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + if (width > 1) + c.weightx = 1.0; + if (height > 1) { + c.weighty = 1.0; + c.fill = GridBagConstraints.BOTH; + } + c.gridx = x; + c.gridy = y; + c.gridwidth = width; + c.gridheight = height; + c.insets = new Insets(2, 10, 2, 10); + return c; + } + + public void showDialog(Evidence evidence) { + this.evidence = evidence; + labelFileName.setText(evidence.getFileName()); + labelPath.setText(evidence.getPath()); + textFieldAlias.setText(evidence.getAlias()); + textFieldPassword.setText(evidence.getPassword()); + textFieldTimeZone.setText(evidence.getTimezone()); + textFieldBlocksize.setText((evidence.getBlocksize() == null) ? "0" : evidence.getBlocksize().toString()); + textAreaMaterial.setText(evidence.getMaterial()); + this.setVisible(true); + + } + + private void saveData() { + if (evidence == null) + return; + evidence.setFileName(labelFileName.getText()); + evidence.setPath(labelPath.getText()); + evidence.setAlias(textFieldAlias.getText()); + evidence.setPassword(textFieldPassword.getText()); + evidence.setTimezone(textFieldTimeZone.getText()); + evidence.setBlocksize(Integer.parseInt(textFieldBlocksize.getText())); + evidence.setMaterial(textAreaMaterial.getText()); + evidenceListListener.forEach(e -> e.evidenceDataChange()); + } + + public void addListener(EvidenceListListener listener) { + evidenceListListener.add(listener); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/EvidenceListListener.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/EvidenceListListener.java new file mode 100644 index 0000000000..332058726c --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/EvidenceListListener.java @@ -0,0 +1,11 @@ +package iped.app.home.newcase.tabs.evidence;/* + * @created 11/12/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +public interface EvidenceListListener { + + public void evidenceDataChange(); + +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/EvidencesTab.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/EvidencesTab.java new file mode 100644 index 0000000000..f8ed4fabcc --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/EvidencesTab.java @@ -0,0 +1,300 @@ +package iped.app.home.newcase.tabs.evidence; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.border.EmptyBorder; +import javax.swing.filechooser.FileSystemView; + +import org.apache.commons.io.FileUtils; + +/* + * @created 09/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import iped.app.home.DefaultPanel; +import iped.app.home.MainFrame; +import iped.app.home.newcase.NewCaseContainerPanel; +import iped.app.home.newcase.model.Evidence; +import iped.app.home.newcase.tabs.evidence.table.EvidencesTableModel; +import iped.app.home.newcase.tabs.evidence.table.TableEvidenceOptionsCellEditor; +import iped.app.home.newcase.tabs.evidence.table.TableEvidenceOptionsCellRenderer; +import iped.app.home.style.StyleManager; +import iped.app.ui.Messages; + +/** + * A page to manage the evidences to be processed + */ +public class EvidencesTab extends DefaultPanel implements EvidenceListListener { + + private JButton buttonAddFolder; + private JButton buttonAddFile; + private JButton buttonAddImages; + private JButton buttonAddPhysicalDrive; + private JTable jtableEvidences; + private EvidencesTableModel evidencesTableModel; + private ArrayList evidencesList; + private final String[] extensoesDeImagensSuportadas = { "raw", "RAW", "000", "001", "vhdx", "VHDX", "dd", "DD", "ex01", "EX01", "E01", "e01", "aff", "AFF", "iso", "ISO", "vhd", "VHD", "vmdk", "VMDK", "ad1", "AD1", "ufdr", "UFDR" }; + + public EvidencesTab(MainFrame mainFrame) { + super(mainFrame); + } + + /** + * Prepare everything to be displayed + */ + protected void createAndShowGUI() { + this.setLayout(new BorderLayout()); + setBorder(new EmptyBorder(10, 10, 10, 10)); + createFormComponentInstances(); + this.add(createTitlePanel(), BorderLayout.NORTH); + this.add(createFormPanel(), BorderLayout.CENTER); + this.add(createNavigationButtonsPanel(), BorderLayout.SOUTH); + } + + /** + * Create a new JPanel instance containing the Page Title + * + * @return - JPanel containing the Page Title + */ + private JPanel createTitlePanel() { + JPanel panelTitle = new JPanel(); + panelTitle.setBackground(Color.white); + JLabel labelTitle = new JLabel(Messages.get("Home.Evidences.Title")); + labelTitle.setFont(StyleManager.getPageTitleFont()); + panelTitle.add(labelTitle); + return panelTitle; + } + + /** + * Create a new JPanel instance containing all inputs + * + * @return JPanel - A JPanel containing all data input form itens + */ + private JPanel createFormPanel() { + JPanel panelForm = new JPanel(); + panelForm.setLayout(new BoxLayout(panelForm, BoxLayout.PAGE_AXIS)); + panelForm.setBackground(Color.white); + setupTableButtonsPanel(panelForm); + panelForm.add(Box.createRigidArea(new Dimension(10, 10))); + setupEvidenceTables(panelForm); + return panelForm; + } + + private void createFormComponentInstances() { + buttonAddFolder = new JButton(Messages.get("Home.Evidences.AddFolder")); + buttonAddFile = new JButton(Messages.get("Home.Evidences.AddFile")); + buttonAddImages = new JButton(Messages.get("Home.Evidences.AddImagesRecursively")); + buttonAddPhysicalDrive = new JButton(Messages.get("Home.Evidences.AddDisk")); + } + + /** + * Create and setup a JPanel containing all buttons to add Evidences to Table + * + * @param panel + * - JPanel containing JButtons + */ + private void setupTableButtonsPanel(JPanel panel) { + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS)); + buttonPanel.setBackground(Color.white); + buttonPanel.add(buttonAddFolder); + buttonAddFolder.addActionListener(e -> { + JFileChooser fileChooserDestino = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory()); + fileChooserDestino.setDialogTitle(Messages.get("Home.Evidences.SelectFolder")); + fileChooserDestino.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + fileChooserDestino.setAcceptAllFileFilterUsed(false); + if (fileChooserDestino.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { + Evidence evidence = new Evidence(); + evidence.setFileName(fileChooserDestino.getSelectedFile().getName()); + evidence.setPath(fileChooserDestino.getSelectedFile().getPath()); + evidencesList.add(evidence); + evidencesTableModel.fireTableDataChanged(); + } + }); + buttonPanel.add(buttonAddFile); + buttonAddFile.addActionListener(e -> { + JFileChooser fileChooser = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory()); + fileChooser.setDialogTitle(Messages.get("Home.Evidences.SelectFile")); + fileChooser.setAcceptAllFileFilterUsed(false); + if (fileChooser.showDialog(this, Messages.get("Home.Evidences.AddFileTitle")) == JFileChooser.APPROVE_OPTION) { + Evidence evidence = new Evidence(); + evidence.setFileName(fileChooser.getSelectedFile().getName()); + evidence.setPath(fileChooser.getSelectedFile().getPath()); + evidencesList.add(evidence); + evidencesTableModel.fireTableDataChanged(); + } + }); + buttonPanel.add(buttonAddImages); + buttonAddImages.addActionListener(e -> { + JFileChooser fileChooserProcurarImagens = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory()); + fileChooserProcurarImagens.setDialogTitle(Messages.get("Home.Evidences.ChooseSourceFolder")); + fileChooserProcurarImagens.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + fileChooserProcurarImagens.setAcceptAllFileFilterUsed(false); + String pastaDeOrigem; + if (fileChooserProcurarImagens.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { + pastaDeOrigem = fileChooserProcurarImagens.getSelectedFile().toString(); + } else { + return; + } + Path path = Paths.get(pastaDeOrigem); + try { + List files = findEvidences(path, extensoesDeImagensSuportadas); + Collections.sort(files); + String prev = null; + for (String current : files) { + if (current.endsWith(".001")) { + String zeroSegment = current.substring(0, current.length() - 3) + "000"; + if (prev != null && prev.equals(zeroSegment)) { + continue; + } + } + File file = new File(current); + Evidence evidence = new Evidence(); + evidence.setFileName(file.getName()); + evidence.setPath(file.getPath()); + evidencesList.add(evidence); + prev = current; + } + evidencesTableModel.fireTableDataChanged(); + } catch (Exception ex) { + System.out.println(Messages.get("Home.Evidences.ImageSearchError")); + } + }); + buttonPanel.add(buttonAddPhysicalDrive); + buttonAddPhysicalDrive.addActionListener(e -> { + DiskSelecionDialog diskSelecionDialog = new DiskSelecionDialog(this.mainFrame, evidencesList); + diskSelecionDialog.addListener(this); + diskSelecionDialog.showDialog(); + + }); + panel.add(buttonPanel); + } + + /** + * Create and setup a JTable do manage all Evidences to be processed + * + * @param panel + * - A JPanel to add JTable + */ + private void setupEvidenceTables(JPanel panel) { + evidencesList = NewCaseContainerPanel.getInstance().getIpedProcess().getEvidenceList(); + EvidenceInfoDialog infoDialog = new EvidenceInfoDialog(mainFrame); + infoDialog.addListener(this); + evidencesTableModel = new EvidencesTableModel(evidencesList, infoDialog); + jtableEvidences = new JTable(); + jtableEvidences.setModel(evidencesTableModel); + setupTableLayout(infoDialog); + panel.add(new JScrollPane(jtableEvidences)); + } + + /** + * Adjusts the JTable layout + */ + private void setupTableLayout(EvidenceInfoDialog infoDialog) { + jtableEvidences.setFillsViewportHeight(true); + jtableEvidences.setRowHeight(30); + StyleManager.setTableHeaderStyle(jtableEvidences); + jtableEvidences.getColumn(jtableEvidences.getColumnName(3)).setCellRenderer(new TableEvidenceOptionsCellRenderer()); + jtableEvidences.getColumn(jtableEvidences.getColumnName(3)).setCellEditor(new TableEvidenceOptionsCellEditor(evidencesList, infoDialog)); + jtableEvidences.getColumn(jtableEvidences.getColumnName(3)).setMaxWidth(70); + } + + /** + * A JPanel containing "Back" and "Next" buttons + * + * @return JPanel - a new JPanel instance containing the bottom page Button + */ + private JPanel createNavigationButtonsPanel() { + JPanel panelButtons = new JPanel(); + panelButtons.setBackground(Color.white); + JButton buttoCancel = new JButton(Messages.get("Home.Back")); + buttoCancel.addActionListener(e -> NewCaseContainerPanel.getInstance().goToPreviousTab()); + JButton buttonNext = new JButton(Messages.get("Home.Next")); + buttonNext.addActionListener(e -> { + if (evidencesList == null || evidencesList.isEmpty()) { + JOptionPane.showMessageDialog(this, Messages.get("Home.Evidences.NoEvidencesAlert"), Messages.get("Home.Evidences.NoEvidencesAlertTitle"), JOptionPane.WARNING_MESSAGE); + return; + } + NewCaseContainerPanel.getInstance().goToNextTab(); + }); + panelButtons.add(buttoCancel); + panelButtons.add(buttonNext); + return panelButtons; + } + + public List findEvidences(Path path, String[] fileExtensions) { + if (!Files.isDirectory(path)) { + throw new IllegalArgumentException(Messages.get("Home.Evidences.PathMustBeDirectory")); + } + File root = path.toFile(); + List result = new ArrayList<>(); + try { + List> resultList = listFiles(root, fileExtensions); + Collection files = resultList.get(0); + for (File file : files) { + result.add(file.getAbsolutePath()); + } + Collection skippedFolders = resultList.get(1); + if (skippedFolders.size() > 0) { + JOptionPane.showMessageDialog(this, Messages.get("Home.Evidences.SkippedFoldersOnRecursiveEvidenceFind"), Messages.get("Home.Evidences.SkippedFoldersOnRecursiveEvidenceFindAlertTitle"), JOptionPane.WARNING_MESSAGE); + } + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } + + private static List> listFiles(File root, String[] fileExtensions) { + List> result = new ArrayList>(); + Collection filesFound = new ArrayList(); + result.add(filesFound); + Collection skippedFolders = new ArrayList(); + result.add(skippedFolders); + listFiles(root, fileExtensions, result); + return result; + } + + private static void listFiles(File root, String[] fileExtensions, List> result) { + Collection filesFound = result.get(0); + Collection skippedFolders = result.get(1); + try { + Collection files = FileUtils.listFiles(root, fileExtensions, false); + for (File file : files) { + filesFound.add(file); + } + for (File file : root.listFiles()) { + if (file.isDirectory()) { + listFiles(file, fileExtensions, result); + } + } + } catch (Exception e) { + skippedFolders.add(root); + } + } + + @Override + public void evidenceDataChange() { + evidencesTableModel.fireTableDataChanged(); + } +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/table/EvidencesTableModel.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/table/EvidencesTableModel.java new file mode 100644 index 0000000000..5f1a9f6bcc --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/table/EvidencesTableModel.java @@ -0,0 +1,88 @@ +package iped.app.home.newcase.tabs.evidence.table; + +import java.util.ArrayList; + +import javax.swing.table.AbstractTableModel; + +/* + * @created 12/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import iped.app.home.newcase.model.Evidence; +import iped.app.home.newcase.tabs.evidence.EvidenceInfoDialog; +import iped.app.ui.Messages; + +public class EvidencesTableModel extends AbstractTableModel { + + private final String[] COLUMN_NAME = { Messages.get("Home.Evidences.Table.FileName"), Messages.get("Home.Evidences.Table.Alias"), Messages.get("Home.Evidences.Table.Path"), Messages.get("Home.Evidences.Table.Options") }; + private final ArrayList evidencesList; + private EvidenceInfoDialog evidenceInfoDialog; + + public EvidencesTableModel(ArrayList evidencesList, EvidenceInfoDialog evidenceInfoDialog) { + this.evidencesList = evidencesList; + this.evidenceInfoDialog = evidenceInfoDialog; + } + + @Override + public Class getColumnClass(int columnIndex) { + return super.getColumnClass(columnIndex); + } + + @Override + public int getRowCount() { + return (evidencesList != null) ? evidencesList.size() : 0; + } + + @Override + public int getColumnCount() { + return COLUMN_NAME.length; + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + if (evidencesList == null) + return ""; + switch (columnIndex) { + case 0: + return evidencesList.get(rowIndex).getFileName(); + case 1: + return evidencesList.get(rowIndex).getAlias(); + case 2: + return evidencesList.get(rowIndex).getPath(); + case 3: + return evidencesList.get(rowIndex); + default: + return ""; + } + } + + @Override + public boolean isCellEditable(int rowIndex, int columnIndex) { + switch (columnIndex) { + case 1: + return true; + case 3: + return true; + default: + return false; + } + } + + @Override + public String getColumnName(int column) { + return COLUMN_NAME[column]; + } + + @Override + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + if (evidencesList == null || evidencesList.isEmpty() || rowIndex >= evidencesList.size()) + return; + Evidence currentEvidence = evidencesList.get(rowIndex); + if (columnIndex == 1) { + currentEvidence.setAlias(String.valueOf(aValue)); + } + } + +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/table/TableEvidenceOptionsCellEditor.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/table/TableEvidenceOptionsCellEditor.java new file mode 100644 index 0000000000..5bff11da57 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/table/TableEvidenceOptionsCellEditor.java @@ -0,0 +1,108 @@ +package iped.app.home.newcase.tabs.evidence.table; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.util.ArrayList; + +import javax.swing.AbstractCellEditor; +import javax.swing.JButton; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.table.TableCellEditor; + +/* + * @created 13/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import iped.app.home.newcase.model.Evidence; +import iped.app.home.newcase.tabs.evidence.EvidenceInfoDialog; + +/** + * The Evidence table cell editor this class is used to create a custom cell to + * the Evidence table here we get the evidence info edit button (... button) and + * the remove row button (x button) + */ +public class TableEvidenceOptionsCellEditor extends AbstractCellEditor implements TableCellEditor { + + private final ArrayList evidencesList; + private EvidenceInfoDialog infoDialog; + + private JPanel evidenceOptionsPanel; + + /** + * TableEvidenceOptionsCellEditor constructor this class gonna be instantiated + * only if user edit the options column cell + * + * @param evidencesList + * - the list of evidences used in the evidences table + * @param infoDialog + * - The evidence editor dialog reference + */ + public TableEvidenceOptionsCellEditor(ArrayList evidencesList, EvidenceInfoDialog infoDialog) { + this.evidencesList = evidencesList; + this.infoDialog = infoDialog; + } + + /** + * @param table + * - Evidence table instance + * @param value + * - Evidence to be edited object reference + * @param isSelected + * - is column selected? + * @param row + * - current row + * @param column + * - current column + * @return - A JPanel containing two buttons to edit or remove + */ + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + System.out.println("TableEvidenceOptionsCellEditor constructor"); + createOptionPanel(row, table); + return evidenceOptionsPanel; + } + + /** + * Create a panel with two buttons, one for evidence info dialog and other to + * remove selected row + * + * @param rowIndex + * - The evidence table current row + * @param table + * - the evidence table + * @return - A JPanel containing two buttons to edit or remove + */ + private JPanel createOptionPanel(int rowIndex, JTable table) { + evidenceOptionsPanel = new JPanel(); + evidenceOptionsPanel.setLayout(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + JButton optionButton = new JButton("..."); + optionButton.addActionListener(e -> infoDialog.showDialog(evidencesList.get(rowIndex))); + evidenceOptionsPanel.add(optionButton, gbc); + JButton removeButton = new JButton("X"); + removeButton.setForeground(Color.RED); + Font newButtonFont = new Font(removeButton.getFont().getName(), Font.BOLD, removeButton.getFont().getSize()); + removeButton.setFont(newButtonFont); + removeButton.addActionListener(e -> { + evidencesList.remove(rowIndex); + ((EvidencesTableModel) table.getModel()).fireTableDataChanged(); + fireEditingStopped(); + }); + evidenceOptionsPanel.add(removeButton, gbc); + return evidenceOptionsPanel; + } + + /** + * @return - A JPanel containing two buttons to edit or remove + */ + @Override + public Object getCellEditorValue() { + return evidenceOptionsPanel; + } + +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/table/TableEvidenceOptionsCellRenderer.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/table/TableEvidenceOptionsCellRenderer.java new file mode 100644 index 0000000000..37cc59e9cb --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/evidence/table/TableEvidenceOptionsCellRenderer.java @@ -0,0 +1,59 @@ +package iped.app.home.newcase.tabs.evidence.table;/* + * @created 13/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import java.awt.Color; +import java.awt.Component; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; + +import javax.swing.JButton; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.table.TableCellRenderer; + +/** + * This class is a renderer for evidences table options columns (the most right + * column) There is no action for button here!! + */ +public class TableEvidenceOptionsCellRenderer extends JPanel implements TableCellRenderer { + + private JPanel renderPanel; + + /** + * Table Evidences, options columns renderer contructor + */ + public TableEvidenceOptionsCellRenderer() { + createRenderPanel(); + } + + /** + * Create a panel with two buttons one for evidence info dialog and other to + * remove selected row Since this is a render cell, there is no button action. + * See {@link TableEvidenceOptionsCellEditor} to debug buttons actions + */ + private void createRenderPanel() { + renderPanel = new JPanel(); + renderPanel.setLayout(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + JButton optionButton = new JButton("..."); + renderPanel.add(optionButton, gbc); + JButton removeButton = new JButton("X"); + removeButton.setForeground(Color.RED); + Font newButtonFont = new Font(removeButton.getFont().getName(), Font.BOLD, removeButton.getFont().getSize()); + removeButton.setFont(newButtonFont); + renderPanel.add(removeButton, gbc); + } + + /** + * Return the panel with the options buttons + */ + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + return renderPanel; + } + +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/process/AbstractTaskClassPopupMenu.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/AbstractTaskClassPopupMenu.java new file mode 100644 index 0000000000..9f686eb9ab --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/AbstractTaskClassPopupMenu.java @@ -0,0 +1,84 @@ +package iped.app.home.newcase.tabs.process; + +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.JTable; + +import org.reflections.Reflections; + +import iped.engine.task.AbstractTask; + +public class AbstractTaskClassPopupMenu extends JPopupMenu implements ActionListener { + + private static final long serialVersionUID = 734426681117556452L; + List taskArrayList; + private JTable jtable; + + class JAbstractTaskClassMenuItem extends JMenuItem { + private static final long serialVersionUID = -2921811070681015925L; + Class taskClass; + + public JAbstractTaskClassMenuItem(Class aClass) { + super(aClass.getName()); + this.taskClass = aClass; + } + + public Class getAbstractTaskClass() { + return taskClass; + } + } + + public AbstractTaskClassPopupMenu(JTable jtable) { + this.jtable = jtable; + this.taskArrayList = ((TasksTableModel) jtable.getModel()).getTaskList(); + List> installedClasses = new ArrayList>(); + for (Iterator iterator = taskArrayList.iterator(); iterator.hasNext();) { + AbstractTask abstractTask = iterator.next(); + installedClasses.add(abstractTask.getClass()); + } + + Reflections reflections = new Reflections("iped.engine.task"); + Set> classes = reflections.getSubTypesOf(iped.engine.task.AbstractTask.class); + for (Class aClass : classes) { + if (!Modifier.isAbstract(aClass.getModifiers())) { + if (!installedClasses.contains(aClass)) { + JMenuItem item = new JAbstractTaskClassMenuItem(aClass); + item.addActionListener(this); + add(item); + } + } + } + } + + @Override + public void actionPerformed(ActionEvent e) { + if (e.getSource() instanceof JAbstractTaskClassMenuItem) { + JAbstractTaskClassMenuItem item = (JAbstractTaskClassMenuItem) e.getSource(); + try { + taskArrayList.add(item.getAbstractTaskClass().getDeclaredConstructor().newInstance()); + this.remove(item); + ((TasksTableModel) jtable.getModel()).fireTableRowsInserted(taskArrayList.size() - 1, taskArrayList.size() - 1); + } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + } + } + + @Override + public void show(Component invoker, int x, int y) { + y = y - this.getPreferredSize().height; + super.show(invoker, x, y); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/process/LineOrderTransferHandler.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/LineOrderTransferHandler.java new file mode 100644 index 0000000000..3c8783a501 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/LineOrderTransferHandler.java @@ -0,0 +1,122 @@ +package iped.app.home.newcase.tabs.process; + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.IOException; + +import javax.swing.JComponent; +import javax.swing.JTable; +import javax.swing.TransferHandler; + +import iped.engine.task.AbstractTask; +import iped.engine.task.PythonTask; +import iped.engine.task.ScriptTask; + +public class LineOrderTransferHandler extends TransferHandler { + int[] indices = null; + + static final String TASK_FLAVOR_NAME = "task"; + static final DataFlavor TASK_FLAVOR = new DataFlavor(AbstractTask.class, TASK_FLAVOR_NAME); + + /** + * We only support importing strings. + */ + public boolean canImport(TransferHandler.TransferSupport info) { + // Check for String flavor + if ((!info.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) && (!info.isDataFlavorSupported(TASK_FLAVOR))) { + return false; + } + return true; + } + + /** + * We support both copy and move actions. + */ + public int getSourceActions(JComponent c) { + return TransferHandler.MOVE; + } + + public boolean importTask(TransferHandler.TransferSupport info) { + AbstractTask task; + + Transferable t = info.getTransferable(); + + JTable tasksTable = (JTable) info.getComponent(); + TasksTableModel tableModel = (TasksTableModel) tasksTable.getModel(); + JTable.DropLocation dl = (JTable.DropLocation) info.getDropLocation(); + int row = dl.getRow(); + boolean insert = dl.isInsertRow(); + + try { + task = (AbstractTask) t.getTransferData(TASK_FLAVOR); + } catch (Exception e) { + return false; + } + + tableModel.changeOrder(indices[0], row); + + return true; + + } + + /** + * Perform the actual import. This demo only supports drag and drop. + */ + public boolean importData(TransferHandler.TransferSupport info) { + if (!info.isDrop()) { + return false; + } + + // Get the string that is being dropped. + Transferable t = info.getTransferable(); + if (t.isDataFlavorSupported(TASK_FLAVOR)) { + return importTask(info); + } + if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { + // return importTask(info); + } + return false; + } + + /** + * Bundle up the selected items in a single list for export. Each line is + * separated by a newline. + */ + protected Transferable createTransferable(JComponent c) { + JTable tasksTable = (JTable) c; + indices = tasksTable.getSelectedRows(); + TasksTableModel tableModel = (TasksTableModel) tasksTable.getModel(); + final AbstractTask task = tableModel.getTaskList().get(indices[0]); + if ((task instanceof PythonTask) || (task instanceof ScriptTask)) { + return new Transferable() { + public boolean isDataFlavorSupported(DataFlavor flavor) { + return flavor.equals(TASK_FLAVOR); + } + + @Override + public DataFlavor[] getTransferDataFlavors() { + DataFlavor[] dataFlavors = new DataFlavor[1]; + dataFlavors[0] = TASK_FLAVOR; + return dataFlavors; + } + + @Override + public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { + return task; + } + }; + } else { + return null; + } + } + + /** + * Remove the items moved from the list. + */ + protected void exportDone(JComponent c, Transferable data, int action) { + JTable tasksTable = (JTable) c; + tasksTable.repaint(); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/process/ProcessOptionTab.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/ProcessOptionTab.java new file mode 100644 index 0000000000..db495211c1 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/ProcessOptionTab.java @@ -0,0 +1,616 @@ +package iped.app.home.newcase.tabs.process; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dialog.ModalityType; +import java.awt.Dimension; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.MouseEvent; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.DropMode; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTabbedPane; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.SwingUtilities; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; + +import iped.app.home.DefaultPanel; +import iped.app.home.MainFrame; +import iped.app.home.configurables.ConfigurablePanel; +import iped.app.home.configurables.ConfigurablePanelFactory; +import iped.app.home.configurables.api.ConfigurableValidationException; +import iped.app.home.configurables.api.IConfigurablePanelFactory; +import iped.app.home.newcase.NewCaseContainerPanel; +import iped.app.home.newcase.model.ExistentCaseOptions; +import iped.app.home.newcase.model.IPEDProcess; +import iped.app.home.processmanager.ProcessManager; +import iped.app.home.style.StyleManager; +import iped.app.ui.Messages; +import iped.configuration.Configurable; +import iped.configuration.EnabledInterface; +import iped.configuration.IConfigurationDirectory; +import iped.engine.config.ConfigurableChangeListener; +import iped.engine.config.ConfigurationDirectory; +import iped.engine.config.ConfigurationManager; +import iped.engine.config.FileSystemConfig; +import iped.engine.config.ProfileManager; +import iped.engine.config.SerializedConfigurationDirectory; +import iped.engine.config.TaskInstallerConfig; +import iped.engine.task.AbstractTask; +import iped.engine.task.ScriptTask; +import iped.exception.IPEDException; + +/* + * @created 13/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + * Patrick Dalla Bernardina + */ +public class ProcessOptionTab extends DefaultPanel implements TableModelListener, ConfigurableChangeListener { + + private JTable jtableTasks; + private TasksTableModel tasksTableModel; + private TaskInstallerConfig taskInstallerConfig;// referece to current task installer being edited + private List taskArrayList;// list of tasks being edited + + JFileChooser scriptChooser = new JFileChooser(); + private JComboBox profilesCombo; + private ConfigurationManager selectedConfigurationManager;// configuration manager corresponding to the current + // profile selected + + /** + * The default config manager will be used as the base line to create the task + * list. Other profiles will only enable or disable these tasks, or add delete + * Script tasks. + */ + private ConfigurationManager defaultConfigurationManager;// configuration manager corresponding to iped default + // distributed configuration + + private JPanel selectProfilePanel; + private JPanel createProfilePanel; + private JTextField tfProfileName; + private JButton buttonStartProcess; + + /** + * Profile representing the configs in "conf" folder. + */ + ConfigurationDirectory baselineProfile; + + private JButton deleteProfileBtn; + private Object[] profilesArray; + private boolean isInsertingProfile; + private JScrollPane fsScrollPanel; + private ConfigurablePanel fsConfigPanel; + + private static final String SELECT_PROFILE_PANEL = "selectProfilePanel"; + private static final String CREATE_PROFILE_PANEL = "createProfilePanel"; + + public ProcessOptionTab(MainFrame mainFrame) { + super(mainFrame); + } + + @Override + protected void createAndShowGUI() { + this.createObjectInstances(); + this.setLayout(new BorderLayout()); + this.add(createTitlePanel(), BorderLayout.NORTH); + + JComponent panelForm = createFormPanel(); + + this.add(panelForm, BorderLayout.CENTER); + this.add(createNavigationButtonsPanel(), BorderLayout.SOUTH); + // show select profile panel and hide create profile panel + // use this method after create createNavigationButtonsPanel to avoid + // NullpointerException + showProfilePanel(SELECT_PROFILE_PANEL); + } + + /** + * Executed on tab initialization. Creates some needed object references. + */ + private void createObjectInstances() { + // create the baseline profile item on profilemanager + baselineProfile = ProfileManager.get().getDefaultProfile(); + ProfileManager.get().addObject(baselineProfile); + + defaultConfigurationManager = ConfigurationManager.get(); + + // for the first time, the selected configuration is the default + selectedConfigurationManager = new ConfigurationManager(baselineProfile); + selectedConfigurationManager.addConfigurableChangeListener(this); + + try { + defaultConfigurationManager.loadConfigs(true); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private JPanel createTitlePanel() { + JPanel panelTitle = new JPanel(); + panelTitle.setBackground(super.getCurrentBackGroundColor()); + JLabel labelTitle = new JLabel(Messages.get("Home.ProcOptions.Title")); + labelTitle.setFont(StyleManager.getPageTitleFont()); + panelTitle.add(labelTitle); + return panelTitle; + } + + private JComponent createFormPanel() { + JPanel panelForm = new JPanel(); + panelForm.setLayout(new BoxLayout(panelForm, BoxLayout.PAGE_AXIS)); + panelForm.setBackground(super.getCurrentBackGroundColor()); + setupSelectProfilesPanel(panelForm); + setupCreateProfilePanel(panelForm); + panelForm.add(Box.createRigidArea(new Dimension(10, 10))); + + JPanel tasksPanel = new JPanel(); + tasksPanel.setLayout(new BoxLayout(tasksPanel, BoxLayout.PAGE_AXIS)); + setupTasksTables(tasksPanel); + + JTabbedPane tabPane = new JTabbedPane(); + tabPane.add("Tasks", tasksPanel); + JPanel fsPanel = new JPanel(); + setupFSConfigPanel(fsPanel); + fsPanel.setLayout(new BoxLayout(fsPanel, BoxLayout.PAGE_AXIS)); + tabPane.add(iped.engine.localization.Messages.getString(FileSystemConfig.class.getName()), fsPanel); + tabPane.setPreferredSize(new Dimension(600, 2000)); + + panelForm.add(tabPane); + + + ItemListener[] listeners = profilesCombo.getItemListeners(); + for (int i = 0; i < listeners.length; i++) { + profilesCombo.removeItemListener(listeners[i]); + } + for (int i = 0; i < profilesArray.length; i++) { + if (((IConfigurationDirectory) profilesArray[i]).getName().equals("default")) { + profilesCombo.setSelectedItem((IConfigurationDirectory) profilesArray[i]); + break; + } + } + for (int i = 0; i < listeners.length; i++) { + profilesCombo.addItemListener(listeners[i]); + } + + loadTasksTables((IConfigurationDirectory) profilesCombo.getSelectedItem()); + + return panelForm; + } + + /** + * Create a Jpanel to user choose a process profile + * + * @param parentPanel + * - a parent panel to add the "select profile panel" + */ + private void setupSelectProfilesPanel(JPanel parentPanel) { + selectProfilePanel = new JPanel(); + deleteProfileBtn = new JButton("Delete"); + parentPanel.add(selectProfilePanel); + selectProfilePanel.setBackground(super.getCurrentBackGroundColor()); + selectProfilePanel.add(new JLabel(Messages.get("Home.ProcOptions.ExecProfile"))); + profilesArray = ProfileManager.get().getObjects().toArray(); + profilesCombo = new JComboBox(profilesArray); + profilesCombo.setPreferredSize(new Dimension(200, (int) profilesCombo.getPreferredSize().getHeight())); + selectProfilePanel.add(profilesCombo); + profilesCombo.setSelectedItem(baselineProfile); + profilesCombo.addItemListener(e -> { + if (e.getStateChange() == ItemEvent.SELECTED) { + IConfigurationDirectory configDirectory = (IConfigurationDirectory) e.getItem(); + if ((e.getStateChange() == ItemEvent.SELECTED) && (!isInsertingProfile)) { + loadTasksTables(configDirectory); + setupFSConfigPanel(null); + } + if (configDirectory instanceof SerializedConfigurationDirectory) { + selectProfilePanel.add(deleteProfileBtn); + } else { + selectProfilePanel.remove(deleteProfileBtn); + } + selectProfilePanel.updateUI(); + } + }); + deleteProfileBtn.addActionListener(e -> { + IConfigurationDirectory configDirectory = (IConfigurationDirectory) profilesCombo.getSelectedItem(); + ProfileManager.get().removeObject(configDirectory); + profilesCombo.removeItemAt(profilesCombo.getSelectedIndex()); + selectProfilePanel.remove(deleteProfileBtn); + }); + } + + /** + * A JPanel to show user options to create a new profile + * + * @param parentPanel + * - a parent panel to add the new "create profile panel" + */ + private void setupCreateProfilePanel(JPanel parentPanel) { + createProfilePanel = new JPanel(); + parentPanel.add(createProfilePanel); + createProfilePanel.setBackground(super.getCurrentBackGroundColor()); + createProfilePanel.add(new JLabel(Messages.get("Home.ProcOptions.NewProfile"))); + + tfProfileName = new JTextField(); + tfProfileName.setBackground(Color.RED); + tfProfileName.setPreferredSize(new Dimension(200, (int) tfProfileName.getPreferredSize().getHeight())); + tfProfileName.setText(((IConfigurationDirectory) profilesCombo.getSelectedItem()).getName()); + createProfilePanel.add(tfProfileName); + + JButton btInsertProfile = new JButton(Messages.get("Home.ProcOptions.CreateNewProfile")); + createProfilePanel.add(btInsertProfile); + btInsertProfile.addActionListener(e -> { + try { + isInsertingProfile = true; + + try { + fsConfigPanel.applyChanges(); + fsConfigPanel.fireChangeListener(new ChangeEvent(this)); + } catch (ConfigurableValidationException e1) { + e1.printStackTrace(); + } + + updateTaskInstallerConfig(); + IConfigurationDirectory dir = ProfileManager.get().createProfile(tfProfileName.getText(), selectedConfigurationManager); + profilesCombo.addItem(dir); + showProfilePanel(SELECT_PROFILE_PANEL); + profilesCombo.setSelectedItem(dir); + } catch (FileAlreadyExistsException e1) { + JOptionPane.showMessageDialog(this, e1.getMessage(), "", JOptionPane.WARNING_MESSAGE); + } finally { + isInsertingProfile = false; + } + }); + + JButton btCancel = new JButton(Messages.get("Home.Cancel")); + btCancel.addActionListener(e -> { + loadTasksTables((IConfigurationDirectory) profilesCombo.getSelectedItem()); + setupFSConfigPanel(null); + showProfilePanel(SELECT_PROFILE_PANEL); + }); + createProfilePanel.add(btCancel); + } + + + /** + * A little function do control the display of create profile panel and select + * profile panel + * + * @param panelName + * - Name of the panel to be displayed + */ + private void showProfilePanel(final String panelName) { + switch (panelName) { + case CREATE_PROFILE_PANEL: { + buttonStartProcess.setEnabled(false); + buttonStartProcess.setToolTipText(Messages.get("Home.ProcOptions.ButtonStarExecTooltip")); + createProfilePanel.setVisible(true); + selectProfilePanel.setVisible(false); + break; + } + case SELECT_PROFILE_PANEL: { + buttonStartProcess.setEnabled(true); + buttonStartProcess.setToolTipText(""); + createProfilePanel.setVisible(false); + selectProfilePanel.setVisible(true); + break; + } + } + } + + + /** + * Update selected profile task installer configurable with the tasks states + * defined in UI. + */ + private void updateTaskInstallerConfig() { + List tasks = new ArrayList<>(); + for (int i = 0; i < tasksTableModel.getRowCount(); i++) { + AbstractTask currentTask = tasksTableModel.getTaskList().get(i); + tasks.add(currentTask); + } + taskInstallerConfig.update(tasks); + } + + private Object clone(Object src) { + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(src); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(bais); + return ois.readObject(); + } catch (IOException | ClassNotFoundException e) { + // supposedly impossible to occur + e.printStackTrace(); + return null; + } + } + + private void loadTasksTables(IConfigurationDirectory selectedDirectory) { + selectedConfigurationManager = new ConfigurationManager(selectedDirectory); + + ConfigurationManager.setCurrentConfigurationManager(selectedConfigurationManager); + selectedConfigurationManager.addConfigurableChangeListener(this); + + Set> configs = defaultConfigurationManager.getObjects(); + for (Configurable config : configs) { + // overwrite if already exists with the clone of default config object + selectedConfigurationManager.addObject((Configurable) clone(config)); + } + + try { + selectedConfigurationManager.loadConfigs(true); + } catch (IOException e1) { + e1.printStackTrace(); + } + // Get a TaskInstallerConfig instance with the TaskInstaller.xml content frin + // the selected profile directory + taskInstallerConfig = selectedConfigurationManager.findObject(TaskInstallerConfig.class); + // if the selected profile dos not has a TaskInstaller.xml, load it from de + // CONFDIR location + if (taskInstallerConfig == null) + taskInstallerConfig = defaultConfigurationManager.findObject(TaskInstallerConfig.class); + // Creates a list with all AbstractTask class instance from the + // TaskInstaller.xml file + taskArrayList = taskInstallerConfig.getNewTaskInstances(); + ArrayList enabled = new ArrayList(); + ArrayList enabledConfigurables = new ArrayList(); + + for (AbstractTask currentTask : taskArrayList) { + List> configurableList = null; + try { + configurableList = currentTask.getConfigurables(); + } catch (Exception e) { + } + if (configurableList == null || configurableList.isEmpty()) { + enabledConfigurables.add(null); + enabled.add(currentTask.isEnabled()); + continue; + } + + EnabledInterface enabledConfigurable = null; + for (Iterator iterator = configurableList.iterator(); iterator.hasNext();) { + Configurable configurable = (Configurable) iterator.next(); + if (configurable instanceof EnabledInterface) { + enabledConfigurable = (EnabledInterface) configurable; + break;// uses the first EnabledInterface found as the main EnabledInterface for task + // enabling + } + } + enabledConfigurables.add(enabledConfigurable); + if (enabledConfigurable != null) { + enabled.add(enabledConfigurable.isEnabled()); + } else { + enabled.add(false); + } + } + + tasksTableModel.updateData(selectedConfigurationManager, taskArrayList, enabled, enabledConfigurables); + jtableTasks.getColumn(jtableTasks.getColumnName(3)) + .setCellRenderer(new TaskTableConfigurablesCellRenderer(selectedConfigurationManager, mainFrame)); + } + + /** + * Create the tasks table + * + * @param parentPanel + * - Panel to show the tasktable + */ + private void setupTasksTables(JPanel parentPanel) { + // Create the table model + tasksTableModel = new TasksTableModel(selectedConfigurationManager, mainFrame, taskArrayList); + tasksTableModel.addTableModelListener(this); + jtableTasks = new JTable() { + @Override + public String getToolTipText(MouseEvent event) { + String tip = null; + java.awt.Point p = event.getPoint(); + int rowIndex = rowAtPoint(p); + try { + if (rowIndex != 0) { + AbstractTask task = (AbstractTask) getValueAt(rowIndex, 2); + String title = iped.engine.localization.Messages.getString(task.getClass().getName(), + task.getName()); + tip = iped.engine.localization.Messages.getString( + task.getClass().getName() + iped.engine.localization.Messages.TOOLTIP_SUFFIX, title); + } + } catch (RuntimeException e1) { + } + + return tip; + } + + }; + setupTableLayout(); + JScrollPane scrollTablePane = new JScrollPane(); + scrollTablePane.setViewportView(jtableTasks); + parentPanel.add(scrollTablePane); + } + + /** + * Create and setup a JTable do manage all Evidences to be processed + * + * @param panel + * - A JPanel to add JTable + */ + private void setupFSConfigPanel(JPanel panel) { + Configurable fsConfig = ConfigurationManager.get().findObject(FileSystemConfig.class); + + IConfigurablePanelFactory configPanelFactory = ConfigurablePanelFactory.getInstance(); + fsConfigPanel = (ConfigurablePanel) configPanelFactory.createConfigurablePanel(null, fsConfig, mainFrame); + + fsConfigPanel.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + selectedConfigurationManager.notifyUpdate(fsConfig); + } + }); + + fsConfigPanel.createConfigurableGUI(); + + if (fsScrollPanel == null) { + fsScrollPanel = new JScrollPane(fsConfigPanel); + panel.add(fsScrollPanel); + } else { + fsScrollPanel.setViewportView(fsConfigPanel); + } + } + + private void setupTableLayout() { + jtableTasks.setFillsViewportHeight(true); + jtableTasks.setRowHeight(30); + jtableTasks.setModel(tasksTableModel); + jtableTasks.getColumn(jtableTasks.getColumnName(3)) + .setCellRenderer(new TaskTableConfigurablesCellRenderer(selectedConfigurationManager, mainFrame)); + jtableTasks.getColumn(jtableTasks.getColumnName(3)) + .setCellEditor(new TableTaskOptionsCellEditor(new JCheckBox())); + + jtableTasks.getColumn(jtableTasks.getColumnName(1)).setCellRenderer( + new TableTaskEnabledCellRenderer(jtableTasks.getDefaultRenderer(jtableTasks.getColumnClass(1)))); + + jtableTasks.getColumn(jtableTasks.getColumnName(2)).setCellRenderer(new TableTaskLabelCellRenderer()); + jtableTasks.getColumn(jtableTasks.getColumnName(2)) + .setCellEditor(new TableTaskOptionsCellEditor(new JCheckBox())); + + jtableTasks.getColumn(jtableTasks.getColumnName(0)).setMaxWidth(30); + jtableTasks.getColumn(jtableTasks.getColumnName(1)).setMaxWidth(30); + jtableTasks.getColumn(jtableTasks.getColumnName(3)).setMaxWidth(60); + + jtableTasks.setTransferHandler(new LineOrderTransferHandler()); + jtableTasks.setDropMode(DropMode.INSERT_ROWS); + // jtableTasks.setDragEnabled(true); + } + + private Component createNavigationButtonsPanel() { + JPanel panelButtons = new JPanel(); + panelButtons.setBackground(super.getCurrentBackGroundColor()); + JButton buttonGoBack = new JButton(Messages.get("Home.Back")); + buttonGoBack.addActionListener(e -> NewCaseContainerPanel.getInstance().goToPreviousTab()); + + JButton buttoAddScriptTask = new JButton(Messages.get("Home.ProcOptions.AddScriptTask")); + buttoAddScriptTask.addActionListener(e -> { + File scriptDir = Paths + .get(System.getProperty(IConfigurationDirectory.IPED_APP_ROOT), TaskInstallerConfig.SCRIPT_BASE) + .toFile(); + File exampleScriptFile = new File(scriptDir, ScriptEditPanel.TEMPLATE_SCRIPT_NAME); + TaskConfigDialog tcd = new TaskConfigDialog(selectedConfigurationManager, new ScriptTask(exampleScriptFile), mainFrame); + tcd.setModalityType(ModalityType.APPLICATION_MODAL); + tcd.setVisible(true); + + AbstractTask addedTask = (AbstractTask) tcd.getScriptTask(); + if (addedTask != null) { + tasksTableModel.addData(addedTask, true); + tasksTableModel.fireTableRowsInserted(taskArrayList.size() - 1, taskArrayList.size() - 1); + selectedConfigurationManager.notifyUpdate(taskInstallerConfig); + } + }); + + buttonStartProcess = new JButton(Messages.get("Home.ProcOptions.StartProcessing")); + buttonStartProcess.addActionListener(e -> { + IPEDProcess ipp = NewCaseContainerPanel.getInstance().getIpedProcess(); + boolean existsCaseOnOutput = false; + try { + ProcessManager.validateCaseOutput(ipp.getCaseOutputPath()); + } catch (IPEDException ex) { + existsCaseOnOutput = true; + // if already has a case in the output directory and the user do not select an + // option in the caseinfotab, show the options again!! + if (ipp.getExistentCaseOption() == null) { + Object[] options = { Messages.get("Home.AppendExistentCase"), + Messages.get("Home.ContinueExistentCase"), Messages.get("Home.RestartExistentCase"), + Messages.get("Case.Cancel") }; + int result = JOptionPane.showOptionDialog(this, + Messages.getString("Home.ProcessManager.ExistentCaseAlertMessage"), + Messages.getString("Home.ProcessManager.ExistentCaseAlertTitle"), + JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[3]); + switch (result) { + case 0: + ipp.setExistentCaseOption(ExistentCaseOptions.APPEND); + break; + case 1: + ipp.setExistentCaseOption(ExistentCaseOptions.CONTINUE); + break; + case 2: + ipp.setExistentCaseOption(ExistentCaseOptions.RESTART); + break; + default: + ipp.setExistentCaseOption(null); + return; + } + } + } + if (!existsCaseOnOutput) + ipp.setExistentCaseOption(null); + String selectedProfile = ((IConfigurationDirectory) profilesCombo.getSelectedItem()).getName(); + if (baselineProfile.getName().equalsIgnoreCase(selectedProfile)) + ipp.setProfile(null); + else + ipp.setProfile(selectedProfile); + + NewCaseContainerPanel.getInstance().startIPEDProcessing(); + }); + + panelButtons.add(buttonGoBack); + // panelButtons.add(buttoAddScriptTask); + panelButtons.add(buttonStartProcess); + return panelButtons; + } + + @Override + public void tableChanged(TableModelEvent e) { + if (e.getType() == TableModelEvent.INSERT) { + jtableTasks.getSelectionModel().setLeadSelectionIndex(e.getLastRow()); + AbstractTask task = ((TasksTableModel) jtableTasks.getModel()).getTaskList().get(e.getLastRow()); + List> configurables = task.getConfigurables(); + if (configurables != null && configurables.size() > 0) { + new TaskConfigDialog(selectedConfigurationManager, task, mainFrame).setVisible(true); + } + } + } + + /** + * A listener for task table item selection this action will show to user a + * panel create a new profile!! + * + */ + @Override + public void onChange(Configurable configurable) { + if (configurable != null) { + Runnable r = new Runnable() { + @Override + public void run() { + showProfilePanel(CREATE_PROFILE_PANEL); + jtableTasks.updateUI(); + } + }; + SwingUtilities.invokeLater(r); + } + } +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/process/ScriptEditPanel.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/ScriptEditPanel.java new file mode 100644 index 0000000000..961eb1b988 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/ScriptEditPanel.java @@ -0,0 +1,373 @@ +package iped.app.home.newcase.tabs.process; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; + +import javax.swing.ButtonGroup; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.JTextField; +import javax.swing.ListCellRenderer; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.text.AbstractDocument; +import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; +import javax.swing.text.DocumentFilter; + +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rtextarea.RTextScrollPane; + +import iped.app.home.MainFrame; +import iped.app.ui.Messages; +import iped.configuration.IConfigurationDirectory; +import iped.engine.config.TaskInstallerConfig; +import iped.engine.task.IScriptTask; +import iped.engine.task.PythonTask; +import iped.engine.task.ScriptTask; +import iped.engine.task.ScriptTaskComplianceException; +import iped.utils.IOUtil; + +public class ScriptEditPanel extends JPanel implements DocumentListener { + protected RSyntaxTextArea textArea; + protected RTextScrollPane txtAreaScroll; + IScriptTask scriptTask; + IScriptTask scriptTaskToSave; + File scriptDir = Paths.get(System.getProperty(IConfigurationDirectory.IPED_APP_ROOT), TaskInstallerConfig.SCRIPT_BASE).toFile(); + private JPanel titlePanel; + private JTextField titleText; + private JButton fileButton; + private JRadioButton rbJavascript; + private JRadioButton rbPython; + boolean insertionMode = false; + private JPanel templatePanel; + private JComboBox cbTemplate; + private JButton btSelectTemplate; + private JPanel scriptLanguagePanel; + static final String TEMPLATE_SCRIPT_NAME = "ExampleScriptTask.js"; + private static final String JAVASCRIPT_TEMPLATE_DIR = "/jstemplates"; + private static final String PYTHON_TEMPLATE_DIR = "/pythontemplates"; + private boolean scriptChanged = false; + boolean isScriptEditable = false; + + public ScriptEditPanel(MainFrame mainFrame, IScriptTask scriptTask) { + super(); + this.scriptTask = scriptTask; + File scriptDir = Paths.get(System.getProperty(IConfigurationDirectory.IPED_APP_ROOT), TaskInstallerConfig.SCRIPT_BASE).toFile(); + File exampleScriptFile = new File(scriptDir, ScriptEditPanel.TEMPLATE_SCRIPT_NAME); + File customScriptDir = Paths.get(System.getProperty(IConfigurationDirectory.IPED_APP_ROOT), TaskInstallerConfig.CUSTOM_SCRIPT_BASE).toFile(); + if (scriptTask.getScriptFileName().equals(exampleScriptFile.getAbsolutePath())) { + insertionMode = true; + isScriptEditable = true; + } else { + // is script file is in custom script path, enable edition + if (scriptTask.getScriptFileName().startsWith(customScriptDir.getAbsolutePath())) { + isScriptEditable = true; + } + } + } + + public ScriptEditPanel(MainFrame mainFrame, IScriptTask scriptTask, boolean isScriptEditable) { + this(mainFrame, scriptTask); + this.isScriptEditable = isScriptEditable; + } + + @Override + public void insertUpdate(DocumentEvent e) { + changedUpdate(e); + } + + @Override + public void removeUpdate(DocumentEvent e) { + changedUpdate(e); + } + + @Override + public void changedUpdate(DocumentEvent e) { + scriptChanged = true; + } + + private void setScriptTask(File destFile) throws ScriptTaskComplianceException { + if (destFile.getName().endsWith(".py")) { + scriptTask = new PythonTask(destFile); + textArea.setSyntaxEditingStyle(RSyntaxTextArea.SYNTAX_STYLE_PYTHON); + } else { + scriptTask = new ScriptTask(destFile); + textArea.setSyntaxEditingStyle(RSyntaxTextArea.SYNTAX_STYLE_JAVASCRIPT); + } + try { + BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(destFile), "UTF-8")); //$NON-NLS-1$ + StringBuffer sb = new StringBuffer(); + String str; + while ((str = in.readLine()) != null) { + sb.append(str + "\n"); + } + in.close(); + textArea.setText(sb.toString()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + protected void createAndShowGUI() { + titlePanel = new JPanel(new BorderLayout()); + + titleText = new JTextField(); + fileButton = new JButton(Messages.get("ScriptEditPanel.ImportScript")); + fileButton.setToolTipText(Messages.get("ScriptEditPanel.ImportScript.tooltip")); + + ScriptEditPanel self = this; + fileButton.addActionListener(new ActionListener() { + private JFileChooser scriptChooser = new JFileChooser(); + + @Override + public void actionPerformed(ActionEvent e) { + int result = scriptChooser.showOpenDialog(self); + if (result == JFileChooser.APPROVE_OPTION) { + File selectedFile = scriptChooser.getSelectedFile(); + + try { + File scriptDir = Paths.get(System.getProperty(IConfigurationDirectory.IPED_APP_ROOT), TaskInstallerConfig.SCRIPT_BASE).toFile(); + File destFile = new File(scriptDir, selectedFile.getName()); + + if (destFile.exists()) { + JOptionPane.showMessageDialog(self, Messages.get("Home.ProcOptions.ScriptAlreadyExists")); + } else { + try { + setScriptTask(destFile); + } catch (Exception ex) { + IOUtil.deleteDirectory(destFile); + throw ex; + } + } + } catch (Exception ex) { + JOptionPane.showMessageDialog(self, ex.getLocalizedMessage()); + } + } + } + }); + + titlePanel.add(new JLabel(Messages.get("ScriptEditPanel.File")), BorderLayout.WEST); + titlePanel.add(titleText, BorderLayout.CENTER); + + templatePanel = new JPanel(new BorderLayout()); + + textArea = new RSyntaxTextArea(20, 60); + textArea.setEditable(isScriptEditable); + + if (insertionMode) { + textArea.setEnabled(false); + + titlePanel.add(templatePanel, BorderLayout.SOUTH); + titlePanel.setEnabled(true);// cannot modify existing script name + titleText.setEnabled(true);// cannot modify existing script name + + ButtonGroup bg = new ButtonGroup(); + rbJavascript = new JRadioButton("Javascript"); + rbPython = new JRadioButton("Python"); + bg.add(rbJavascript); + bg.add(rbPython); + scriptLanguagePanel = new JPanel(); + scriptLanguagePanel.add(rbJavascript); + scriptLanguagePanel.add(rbPython); + + rbJavascript.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + changeToJavascript(); + } + }); + + rbPython.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + changeToPython(); + } + }); + + changeToJavascript(); + } else { + titlePanel.setEnabled(false);// cannot modify existing script name + titleText.setEnabled(false);// cannot modify existing script name + } + + try { + if (scriptTask != null) { + String scriptName = scriptTask.getScriptFileName(); + + File scriptFile = new File(scriptName); + titleText.setText(scriptName.substring(0, scriptName.lastIndexOf(".")).substring(scriptName.lastIndexOf(File.separator) + 1)); + + setScriptTask(scriptFile); + } + + textArea.setAutoscrolls(true); + textArea.getDocument().addDocumentListener(this); + ((AbstractDocument) textArea.getDocument()).setDocumentFilter(new DocumentFilter() { + @Override + public void remove(FilterBypass fb, int offset, int length) throws BadLocationException { + if (scriptChanged || confirmChange()) { + super.remove(fb, offset, length); + } + } + + @Override + public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException { + if (scriptChanged || confirmChange()) { + super.insertString(fb, offset, string, attr); + } + } + + @Override + public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { + if (scriptChanged || confirmChange()) { + super.replace(fb, offset, length, text, attrs); + } + } + }); + txtAreaScroll = new RTextScrollPane(); + txtAreaScroll.setViewportView(textArea); + txtAreaScroll.setAutoscrolls(true); + txtAreaScroll.setLineNumbersEnabled(true); + this.setLayout(new BorderLayout()); + this.add(titlePanel, BorderLayout.NORTH); + this.add(txtAreaScroll, BorderLayout.CENTER); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void changeToJavascript() { + changeTo(ScriptEditPanel.JAVASCRIPT_TEMPLATE_DIR); + } + + private void changeToPython() { + changeTo(ScriptEditPanel.PYTHON_TEMPLATE_DIR); + } + + private void changeTo(String folderName) { + templatePanel.removeAll(); + templatePanel.add(scriptLanguagePanel, BorderLayout.NORTH); + File scriptDir = Paths.get(System.getProperty(IConfigurationDirectory.IPED_APP_ROOT), TaskInstallerConfig.SCRIPT_BASE + folderName).toFile(); + if (scriptDir != null) { + File[] files = scriptDir.listFiles(); + if (files != null) { + cbTemplate = new JComboBox(files); + cbTemplate.setSelectedIndex(-1); + templatePanel.add(new JLabel(Messages.get("ScriptEditPanel.SelectTemplateLabel")), BorderLayout.WEST); + templatePanel.add(cbTemplate, BorderLayout.CENTER); + cbTemplate.setRenderer(new ListCellRenderer() { + JLabel result = new JLabel(); + + public Component getListCellRendererComponent(JList list, File value, int index, boolean isSelected, boolean cellHasFocus) { + if (value == null) { + result.setText(""); + } else { + result.setText(value.getName()); + } + return result; + } + }); + + cbTemplate.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + try { + setScriptTask((File) cbTemplate.getSelectedItem()); + } catch (ScriptTaskComplianceException e1) { + e1.printStackTrace(); + } + } + }); + } + templatePanel.add(new JLabel(Messages.get("ScriptEditPanel.Preview")), BorderLayout.SOUTH); + btSelectTemplate = new JButton(Messages.get("ScriptEditPanel.StartEditing")); + btSelectTemplate.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + templatePanel.setVisible(false); + templatePanel.updateUI(); + textArea.setEditable(true); + textArea.setEnabled(true); + } + }); + + JPanel templateButtons = new JPanel(); + templateButtons.add(btSelectTemplate); + templateButtons.add(fileButton); + templatePanel.add(templateButtons, BorderLayout.EAST); + + templatePanel.updateUI(); + } + if (textArea != null) { + textArea.setText(""); + textArea.clearParsers(); + } + } + + public void applyChanges() throws ScriptTaskComplianceException { + if (scriptChanged) { + + File scriptDir = Paths.get(System.getProperty(IConfigurationDirectory.IPED_APP_ROOT), TaskInstallerConfig.CUSTOM_SCRIPT_BASE).toFile(); + String extension = ".js"; + if (scriptTask instanceof PythonTask) { + extension = ".py"; + } + File destFile = new File(scriptDir, titleText.getText() + extension); + + if (insertionMode) { + if (rbPython.isSelected()) { + scriptTask = new PythonTask(destFile); + scriptTask.checkTaskCompliance(textArea.getText()); + + try { + Files.write(destFile.toPath(), textArea.getText().getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } else { + scriptTask.checkTaskCompliance(textArea.getText()); + + try { + Files.write(destFile.toPath(), textArea.getText().getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + scriptTask = new ScriptTask(destFile); + } + } + + scriptTaskToSave = scriptTask; + } + } + + public IScriptTask getScriptTask() { + return scriptTaskToSave; + } + + public boolean confirmChange() { + int result = JOptionPane.showConfirmDialog(this, Messages.get("ScriptEditPanel.scriptScopeWarn")); + return result == JOptionPane.YES_OPTION; + } + +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/process/TableCellRendererUtil.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/TableCellRendererUtil.java new file mode 100644 index 0000000000..533f68ad55 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/TableCellRendererUtil.java @@ -0,0 +1,22 @@ +package iped.app.home.newcase.tabs.process; + +import java.awt.Color; + +import javax.swing.JTable; +import javax.swing.UIManager; + +public class TableCellRendererUtil { + + public static Color getBackground(JTable table, int row, boolean isSelected) { + if (isSelected) { + return table.getSelectionBackground(); + } else if (row % 2 != 0) { + Color c = UIManager.getColor("Table.alternateRowColor"); + return c != null ? new Color(c.getRGB()) : null; + } else { + Color c = UIManager.getColor("Table.background"); + return c != null ? new Color(c.getRGB()) : null; + } + } + +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/process/TableTaskEnabledCellRenderer.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/TableTaskEnabledCellRenderer.java new file mode 100644 index 0000000000..66f850f028 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/TableTaskEnabledCellRenderer.java @@ -0,0 +1,43 @@ +package iped.app.home.newcase.tabs.process; + +import java.awt.Component; + +import javax.swing.JCheckBox; +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.TableCellRenderer; + +public class TableTaskEnabledCellRenderer extends DefaultTableCellRenderer { + TableCellRenderer wrapped; + private JLabel emptyLabel; + boolean showUnremovableCheckBox = true; + + public TableTaskEnabledCellRenderer(TableCellRenderer wrapped) { + this.wrapped = wrapped; + this.emptyLabel = new JLabel(); + } + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + if (column == 1) { + TasksTableModel tm = (TasksTableModel) table.getModel(); + if (tm.isCellEditable(row, column)) { + JCheckBox checkbox = (JCheckBox) wrapped.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + checkbox.setEnabled(true); + return checkbox; + } else { + if (showUnremovableCheckBox) { + JCheckBox checkbox = (JCheckBox) wrapped.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + checkbox.setEnabled(false); + checkbox.setSelected(true); + return checkbox; + } else { + return emptyLabel; + } + } + } + return wrapped.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/process/TableTaskLabelCellRenderer.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/TableTaskLabelCellRenderer.java new file mode 100644 index 0000000000..ac536e8591 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/TableTaskLabelCellRenderer.java @@ -0,0 +1,82 @@ +package iped.app.home.newcase.tabs.process; + +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Image; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; + +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.SwingConstants; +import javax.swing.table.DefaultTableCellRenderer; + +import iped.app.ui.App; +import iped.engine.task.AbstractTask; +import iped.engine.task.IScriptTask; +import iped.utils.IconUtil; + +public class TableTaskLabelCellRenderer extends DefaultTableCellRenderer { + private ImageIcon dragIcon; + private static final String resPath = '/' + App.class.getPackageName().replace('.', '/') + '/'; + + public TableTaskLabelCellRenderer() { + super(); + Image img = (new ImageIcon(IconUtil.class.getResource(resPath + "cursor-hand-icon.png"))).getImage(); + Image newimg = img.getScaledInstance(16, 16, java.awt.Image.SCALE_SMOOTH); + this.dragIcon = new ImageIcon(newimg); + } + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + AbstractTask currentTask = (AbstractTask) value; + JPanel panel = new JPanel(); + panel.setOpaque(true); + panel.setBackground(TableCellRendererUtil.getBackground(table, row, isSelected)); + panel.setLayout(new FlowLayout(FlowLayout.LEFT)); + JLabel nameLabel = new JLabel(); + String localizedName; + if (currentTask instanceof IScriptTask) { + localizedName = iped.engine.localization.Messages.getString(currentTask.getClass().getName() + "." + currentTask.getName(), currentTask.getName()); + } else { + localizedName = iped.engine.localization.Messages.getString(currentTask.getClass().getName(), currentTask.getName()); + } + nameLabel.setText(localizedName); + panel.add(nameLabel, BorderLayout.WEST); + + if ((currentTask instanceof IScriptTask) && (table.getDragEnabled())) { + JButton taskStartDragButton = new JButton(dragIcon); + taskStartDragButton.setVerticalAlignment(SwingConstants.CENTER); + + taskStartDragButton.addActionListener(e -> { + Robot robot; + try { + // simulate mouse click with shift pressed to start dragging + robot = new Robot(); + Point point = panel.getLocationOnScreen(); // rect is my custom view + robot.mouseMove(point.x, point.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + } catch (AWTException e1) { + e1.printStackTrace(); + } + }); + taskStartDragButton.setPreferredSize(new Dimension(20, 25)); + taskStartDragButton.setOpaque(false); + taskStartDragButton.setContentAreaFilled(false); + taskStartDragButton.setBorderPainted(false); + + panel.add(taskStartDragButton, BorderLayout.WEST); + } + + return panel; + + } + +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/process/TableTaskOptionsCellEditor.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/TableTaskOptionsCellEditor.java new file mode 100644 index 0000000000..98643af4a0 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/TableTaskOptionsCellEditor.java @@ -0,0 +1,23 @@ +package iped.app.home.newcase.tabs.process;/* + * @created 13/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import java.awt.Component; + +import javax.swing.DefaultCellEditor; +import javax.swing.JCheckBox; +import javax.swing.JTable; + +public class TableTaskOptionsCellEditor extends DefaultCellEditor { + + public TableTaskOptionsCellEditor(JCheckBox checkBox) { + super(checkBox); + } + + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + return table.getCellRenderer(row, column).getTableCellRendererComponent(table, value, isSelected, isSelected, row, column); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/process/Task.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/Task.java new file mode 100644 index 0000000000..d91560c82e --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/Task.java @@ -0,0 +1,36 @@ +package iped.app.home.newcase.tabs.process;/* + * @created 13/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +public class Task { + + private boolean isEnabled; + private String name; + private String information; + + public boolean isEnabled() { + return isEnabled; + } + + public void setEnabled(boolean enabled) { + isEnabled = enabled; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getInformation() { + return information; + } + + public void setInformation(String information) { + this.information = information; + } +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/process/TaskConfigDialog.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/TaskConfigDialog.java new file mode 100644 index 0000000000..d8e10442d1 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/TaskConfigDialog.java @@ -0,0 +1,209 @@ +package iped.app.home.newcase.tabs.process;/* + * @created 16/12/2022 + * @project IPED + * @author Patrick Dalla Bernardina + * @author Thiago S. Figueiredo + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; + +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.UIManager; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.plaf.basic.BasicTabbedPaneUI; + +import iped.app.home.MainFrame; +import iped.app.home.configurables.ConfigurablePanelFactory; +import iped.app.home.configurables.api.ConfigurableValidationException; +import iped.app.home.configurables.api.IConfigurablePanel; +import iped.app.home.configurables.api.IConfigurablePanelFactory; +import iped.app.home.style.StyleManager; +import iped.app.ui.Messages; +import iped.app.ui.controls.DisabledPanel; +import iped.configuration.Configurable; +import iped.configuration.EnabledInterface; +import iped.engine.config.ConfigurationManager; +import iped.engine.config.EnableTaskProperty; +import iped.engine.task.AbstractTask; +import iped.engine.task.IScriptTask; +import iped.engine.task.ScriptTaskComplianceException; + +public class TaskConfigDialog extends JDialog { + private List> configurables; + private HashMap, IConfigurablePanel> configurablePanels = new HashMap, IConfigurablePanel>(); + AbstractTask task; + ConfigurationManager configurationManager; + MainFrame mainFrame; + private ScriptEditPanel scriptPanel; + IConfigurablePanelFactory configPanelFactory = new ConfigurablePanelFactory(); + HashSet enableTaskProperties = new HashSet(); + private JTabbedPane tabbedPane; + private HashMap changedEnabledProperties = new HashMap(); + + public TaskConfigDialog(ConfigurationManager configurationManager, AbstractTask task, MainFrame mainFrame) { + super(mainFrame); + this.mainFrame = mainFrame; + this.configurationManager = configurationManager; + this.task = task; + setModal(true); + JPanel formPanel = new JPanel(new BorderLayout()); + configurables = task.getConfigurables(); + String localizedName = iped.engine.localization.Messages.getString(task.getClass().getName(), task.getName()); + createTabbedPanel(); + formPanel.add(createTitlePanel(localizedName), BorderLayout.NORTH); + formPanel.add(tabbedPane, BorderLayout.CENTER); + formPanel.add(createButtonsPanel(), BorderLayout.SOUTH); + this.getContentPane().add(formPanel); + this.setBounds(0, 0, (mainFrame.getWidth()), (mainFrame.getHeight() - 50)); + this.setLocationRelativeTo(null); + } + + private JPanel createTitlePanel(String titleText) { + JPanel panelTitle = new JPanel(); + JLabel labelTitle = new JLabel(titleText); + labelTitle.setFont(StyleManager.getPageTitleFont()); + panelTitle.setBackground(Color.white); + panelTitle.add(labelTitle, BorderLayout.CENTER); + + return panelTitle; + } + + /** + * Setup and create a new JTabbedPane instance Here is created a instance of all + * nested JPanels + * + * @return JTabbedPane + */ + private JTabbedPane createTabbedPanel() { + tabbedPane = new JTabbedPane(JTabbedPane.TOP); + tabbedPane.setUI(new BasicTabbedPaneUI() { + @Override + protected int calculateTabHeight(int tabPlacement, int tabIndex, int fontHeight) { + return 25; + } + + }); + + String enabledStr = iped.engine.localization.Messages.getString("Home.Configurable.Enable", "Enable"); + String disabledStr = iped.engine.localization.Messages.getString("Home.Configurable.Disnable", "Disable"); + + if (configurables != null) { + for (Iterator iterator = configurables.iterator(); iterator.hasNext();) { + Configurable configurable = (Configurable) iterator.next(); + if (!(configurable instanceof EnableTaskProperty)) { + IConfigurablePanel configPanel = configPanelFactory.createConfigurablePanel(task, configurable, mainFrame); + + configPanel.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + configurationManager.notifyUpdate(configurable); + } + }); + + configPanel.createConfigurableGUI(); + configurablePanels.put(configurable, configPanel); + String localizedName = iped.engine.localization.Messages.getString(configurable.getClass().getName(), configurable.getClass().getSimpleName()); + String localizedTooltip = iped.engine.localization.Messages.getString(configurable.getClass().getName() + iped.engine.localization.Messages.TOOLTIP_SUFFIX, ""); + if (configurable instanceof EnabledInterface) { + JPanel ckPanel = new JPanel(); + ckPanel.setOpaque(false); + JCheckBox ck = new JCheckBox(); + ckPanel.add(ck); + DisabledPanel disablePanel = new DisabledPanel(configPanel.getPanel(), new Color(200, 200, 200, 150)); + ck.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + changedEnabledProperties.put((EnabledInterface) configurable, ck); + disablePanel.setEnabled(ck.isSelected()); + } + }); + ckPanel.add(new JLabel(enabledStr + " " + localizedName)); + ck.setSelected(((EnabledInterface) configurable).isEnabled()); + disablePanel.setEnabled(ck.isSelected()); + JPanel enabledConfigPanel = new JPanel(); + enabledConfigPanel.setLayout(new BorderLayout()); + enabledConfigPanel.add(ckPanel, BorderLayout.NORTH); + enabledConfigPanel.add(disablePanel, BorderLayout.CENTER); + tabbedPane.addTab(localizedName, UIManager.getIcon("FileView.fileIcon"), enabledConfigPanel, localizedTooltip); + } else { + tabbedPane.addTab(localizedName, UIManager.getIcon("FileView.fileIcon"), configPanel.getPanel(), localizedTooltip); + } + } + if (configurable instanceof EnableTaskProperty) { + enableTaskProperties.add((EnableTaskProperty) configurable); + } + } + } + if (task instanceof IScriptTask) { + scriptPanel = new ScriptEditPanel(mainFrame, (IScriptTask) task); + scriptPanel.createAndShowGUI(); + tabbedPane.addTab("Script", UIManager.getIcon("FileView.fileIcon"), scriptPanel, ""); + } + return tabbedPane; + } + + private Component createButtonsPanel() { + JButton btCancel = new JButton(Messages.get("Home.Cancel")); + btCancel.addActionListener(e -> { + this.setVisible(false); + }); + JButton btSave = new JButton(Messages.get("Home.Save")); + btSave.addActionListener(e -> { + try { + boolean hasOneEnabledChanged = false; + if (changedEnabledProperties.size() > 0) { + // apply checkbox states to respective configurables + for (Iterator iterator = changedEnabledProperties.keySet().iterator(); iterator.hasNext();) { + EnabledInterface enabledInterface = (EnabledInterface) iterator.next(); + enabledInterface.setEnabled(changedEnabledProperties.get(enabledInterface).isSelected()); + configurationManager.notifyUpdate((Configurable) enabledInterface); + hasOneEnabledChanged = true; + } + } + for (Iterator iterator = configurables.iterator(); iterator.hasNext();) { + Configurable configurable = (Configurable) iterator.next(); + if (!(configurable instanceof EnableTaskProperty)) { + IConfigurablePanel configPanel = configurablePanels.get(configurable); + if (configPanel.hasChanged() || hasOneEnabledChanged) { + configPanel.applyChanges(); + configPanel.fireChangeListener(new ChangeEvent(this)); + } + } + } + if (task instanceof IScriptTask) { + scriptPanel.applyChanges(); + task = (AbstractTask) scriptPanel.getScriptTask(); + } + this.setVisible(false); + } catch (ConfigurableValidationException | ScriptTaskComplianceException cve) { + JOptionPane.showMessageDialog(this, cve.getMessage() + "\n" + cve.getCause(), "", JOptionPane.WARNING_MESSAGE); + } + }); + + JPanel panelButtons = new JPanel(); + panelButtons.setBackground(Color.white); + panelButtons.add(btSave); + panelButtons.add(btCancel); + return panelButtons; + } + + public IScriptTask getScriptTask() { + return scriptPanel.getScriptTask(); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/process/TaskTableConfigurablesCellRenderer.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/TaskTableConfigurablesCellRenderer.java new file mode 100644 index 0000000000..80bc1a3c62 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/TaskTableConfigurablesCellRenderer.java @@ -0,0 +1,80 @@ +package iped.app.home.newcase.tabs.process; + +import java.awt.Color; +import java.awt.Component; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.util.List; + +import javax.swing.JButton; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.SwingConstants; +import javax.swing.table.TableCellRenderer; + +import iped.app.home.MainFrame; +import iped.configuration.Configurable; +import iped.engine.config.ConfigurationManager; +import iped.engine.config.EnableTaskProperty; +import iped.engine.config.HashDBLookupConfig; +import iped.engine.task.AbstractTask; +import iped.engine.task.IScriptTask; + +public class TaskTableConfigurablesCellRenderer implements TableCellRenderer { + ConfigurationManager configurationManager; + MainFrame mainFrame; + + public TaskTableConfigurablesCellRenderer(ConfigurationManager configurationManager, MainFrame mainFrame) { + this.configurationManager = configurationManager; + this.mainFrame = mainFrame; + } + + @Override + public Component getTableCellRendererComponent(JTable table, Object cellValue, boolean isSelected, boolean hasFocus, int row, int column) { + + AbstractTask task = (AbstractTask) cellValue; + int count = 0; // counts the number of non EnableTaskProperty configurables + Exception configurableLoadException = null; + + List> configurables = null; + try { + configurables = task.getConfigurables(); + } catch (Exception e) { + configurableLoadException = e; + } + + if (configurables != null) { + for (Configurable value : configurables) { + if (!(value instanceof EnableTaskProperty) && !(value instanceof HashDBLookupConfig)) { + count++; + } + } + } + + JPanel panel = new JPanel(); + panel.setBackground(TableCellRendererUtil.getBackground(table, row, isSelected)); + + if (count > 0 || task instanceof IScriptTask) { + panel.setLayout(new GridBagLayout()); + + GridBagConstraints gbc = new GridBagConstraints(); + JButton taskOptionButton = new JButton("..."); + if (configurableLoadException != null) { + taskOptionButton.setBackground(Color.RED); + String errorMsg = configurableLoadException.getMessage(); + if (errorMsg == null) + errorMsg = configurableLoadException.getClass().getCanonicalName(); + String finalErrorMsg = errorMsg; + taskOptionButton.addActionListener(e -> JOptionPane.showMessageDialog(panel, "Error loading configurables: " + finalErrorMsg)); + } else { + taskOptionButton.addActionListener(e -> new TaskConfigDialog(ConfigurationManager.get(), task, mainFrame).setVisible(true)); + } + taskOptionButton.setVerticalAlignment(SwingConstants.CENTER); + + panel.add(taskOptionButton, gbc); + } + return panel; + } + +} diff --git a/iped-app/src/main/java/iped/app/home/newcase/tabs/process/TasksTableModel.java b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/TasksTableModel.java new file mode 100644 index 0000000000..5518e7c132 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/newcase/tabs/process/TasksTableModel.java @@ -0,0 +1,204 @@ +package iped.app.home.newcase.tabs.process;/* + * @created 13/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.swing.JOptionPane; +import javax.swing.table.AbstractTableModel; + +import iped.app.home.MainFrame; +import iped.app.ui.Messages; +import iped.configuration.Configurable; +import iped.configuration.EnabledInterface; +import iped.engine.config.ConfigurationManager; +import iped.engine.config.LocalConfig; +import iped.engine.config.TaskInstallerConfig; +import iped.engine.task.AbstractTask; +import iped.engine.task.HashDBLookupTask; + +public class TasksTableModel extends AbstractTableModel { + + private static final long serialVersionUID = 3318254202725499526L; + + private final String[] COLLUM_NAME = { "#", " ", "Task", Messages.get("Home.ProcOptions.Table.Options") }; + private ConfigurationManager configurationManager; + private List taskList; + private ArrayList enabled = new ArrayList(); + private ArrayList enabledConfigurables = new ArrayList(); + MainFrame mainFrame; + + private final TaskInstallerConfig taskInstallerConfig; + + public TasksTableModel(ConfigurationManager configurationManager, MainFrame mainFrame, List taskList) { + this.configurationManager = configurationManager; + this.taskInstallerConfig = configurationManager.findObject(TaskInstallerConfig.class); + this.taskList = taskList; + this.mainFrame = mainFrame; + + } + + public List getTaskList() { + return taskList; + } + + public void addData(int row, AbstractTask task, Boolean enabled) { + this.taskList.add(row, task); + this.enabled.add(row, enabled); + List> configs = task.getConfigurables(); + Configurable enableConfigurable = null; + Configurable configurable; + if (configs != null && configs.size() > 0) { + for (Iterator iterator = configs.iterator(); iterator.hasNext();) { + configurable = (Configurable) iterator.next(); + if (configurable instanceof EnabledInterface) { + enableConfigurable = configurable; + } + } + } + this.enabledConfigurables.add(row, (EnabledInterface) enableConfigurable); + + } + + public void addData(AbstractTask task, Boolean enabled) { + addData(taskList.size(), task, enabled); + } + + public void updateData(ConfigurationManager configurationManager, List taskList, ArrayList enabled, ArrayList enabledConfigurable) { + this.taskList = taskList; + this.configurationManager = configurationManager; + this.enabled = enabled; + this.enabledConfigurables = enabledConfigurable; + this.fireTableDataChanged(); + } + + @Override + public int getRowCount() { + return (taskList != null) ? taskList.size() : 0; + } + + @Override + public int getColumnCount() { + return COLLUM_NAME.length; + } + + @Override + public Class getColumnClass(int columnIndex) { + switch (columnIndex) { + case 0: + return Integer.class; + case 1: + return Boolean.class; + case 2: + return AbstractTask.class; + case 3: + return AbstractTask.class; + default: + return String.class; + } + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + if (taskList == null) + return ""; + List> configs; + switch (columnIndex) { + // Task order column + case 0: + return rowIndex + 1; + // Task checkbox column + case 1: + return (enabledConfigurables.get(rowIndex) != null) ? enabledConfigurables.get(rowIndex).isEnabled() : enabled.get(rowIndex); + // task name column + case 2: + return taskList.get(rowIndex); + // options button column + case 3: { + return taskList.get(rowIndex); + } + default: + return ""; + } + } + + @Override + public boolean isCellEditable(int rowIndex, int columnIndex) { + switch (columnIndex) { + case 0: + return false;// task order column + case 1: + return enabledConfigurables.get(rowIndex) != null; // Checkbox column + case 2: + return true;// task name column + case 3: + return true;// Option button column + default: + return false; + } + } + + @Override + public String getColumnName(int column) { + return COLLUM_NAME[column]; + } + + @Override + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + // Enable-disable Column + if (columnIndex == 1) { + if (taskList.get(rowIndex) instanceof HashDBLookupTask) { + if (((boolean) aValue)) { + LocalConfig lc = (LocalConfig) configurationManager.findObject(LocalConfig.class); + if (lc.getHashDbFile() == null) { + JOptionPane.showMessageDialog(mainFrame, "The local hash database file must be configured first in Local environment configuration to enable this task.", "HashDB task", JOptionPane.ERROR_MESSAGE); + return; + } + } + } + enabled.set(rowIndex, ((boolean) aValue)); + EnabledInterface ec = enabledConfigurables.get(rowIndex); + ec.setEnabled((boolean) aValue); + configurationManager.notifyUpdate((Configurable) ec); + configurationManager.notifyUpdate(taskInstallerConfig); + } + } + + public void setEnabled(List enabledTaskArrayList) { + for (AbstractTask abstractTask : enabledTaskArrayList) { + int j = taskList.indexOf(abstractTask); + if (j > -1) { + enabled.set(j, true); + } + } + } + + public boolean getEnabled(int rowIndex) { + return enabled.get(rowIndex); + } + + public void removeRow(int i) { + enabled.remove(i); + taskList.remove(i); + enabledConfigurables.remove(i); + } + + public void changeOrder(int i, int row) { + if (i != row) { + taskList.add(row, taskList.get(i)); + enabled.add(row, enabled.get(i)); + enabledConfigurables.add(row, enabledConfigurables.get(i)); + if (i > row) { + i++; + } + enabled.remove(i); + taskList.remove(i); + enabledConfigurables.remove(i); + configurationManager.notifyUpdate(taskInstallerConfig); + } + } +} diff --git a/iped-app/src/main/java/iped/app/home/opencase/CaseTableCellRender.java b/iped-app/src/main/java/iped/app/home/opencase/CaseTableCellRender.java new file mode 100644 index 0000000000..9668b9be3f --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/opencase/CaseTableCellRender.java @@ -0,0 +1,109 @@ +package iped.app.home.opencase;/* + * @created 29/12/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import static java.util.Comparator.comparing; + +import java.awt.Component; +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.stream.Collectors; + +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.table.DefaultTableCellRenderer; + +import org.apache.commons.lang3.StringUtils; + +import iped.app.home.style.StyleManager; +import iped.app.ui.Messages; +import iped.engine.data.ReportInfo; + +public class CaseTableCellRender extends DefaultTableCellRenderer { + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + DefaultTableCellRenderer result = (DefaultTableCellRenderer) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + Path casePath = (Path) value; + // Check if caseinfo file exists + ReportInfo reportInfo = getCaseInfoFromPath(casePath); + JPanel rowPanel = reportInfo != null ? getCaseInfoJPanel(reportInfo, casePath) : getPathJLabel(casePath); + setRowBackgroundColor(row, isSelected, rowPanel, hasFocus); + rowPanel.setBorder(BorderFactory.createEmptyBorder(3, 15, 3, 15)); + table.setRowHeight(row, (int) rowPanel.getPreferredSize().getHeight()); + return rowPanel; + } + + private void setRowBackgroundColor(int row, boolean isSelected, JPanel casePanel, boolean hasFocus) { + if (isSelected) + casePanel.setBackground(StyleManager.getColumnRowSelectedBackground()); + else + casePanel.setBackground(StyleManager.getColumnRowUnSelectedBackground(row)); + if (hasFocus) + casePanel.setBorder(StyleManager.getColumnRowFocusBorder()); + + } + + private JPanel getPathJLabel(Path casePath) { + JPanel casePanel = new JPanel(); + casePanel.setLayout(new BoxLayout(casePanel, BoxLayout.LINE_AXIS)); + casePanel.add(getCasePathJlabel(casePath)); + return casePanel; + } + + private JLabel getCasePathJlabel(Path casePath) { + return new JLabel(getLabelText("Home.OpenCase.CaseLocation", casePath.toString())); + } + + private JPanel getCaseInfoJPanel(ReportInfo reportInfo, Path casePath) { + JPanel casePanel = new JPanel(); + casePanel.setLayout(new BoxLayout(casePanel, BoxLayout.PAGE_AXIS)); + casePanel.add(getCasePathJlabel(casePath)); + if (!StringUtils.isBlank(reportInfo.caseNumber)) + casePanel.add(new JLabel(getLabelText("ReportDialog.Investigation", reportInfo.caseNumber))); + if (!StringUtils.isBlank(reportInfo.reportTitle)) + casePanel.add(new JLabel(getLabelText("ReportDialog.ReportTitle", reportInfo.reportTitle))); + if (!(reportInfo.investigatedName == null || reportInfo.investigatedName.isEmpty())) + casePanel.add(new JLabel(getLabelText("ReportDialog.InvestigatedNames", reportInfo.investigatedName.stream().map(String::trim).collect(Collectors.joining(", "))))); + if (!StringUtils.isBlank(reportInfo.requestDate)) + casePanel.add(new JLabel(getLabelText("ReportDialog.RequestDate", reportInfo.requestDate))); + if (!StringUtils.isBlank(reportInfo.requester)) + casePanel.add(new JLabel(getLabelText("ReportDialog.Requester", reportInfo.requester))); + if (!StringUtils.isBlank(reportInfo.organizationName)) + casePanel.add(new JLabel(getLabelText("ReportDialog.organizationName", reportInfo.organizationName))); + if (!(reportInfo.examiners == null || reportInfo.examiners.isEmpty())) + casePanel.add(new JLabel(getLabelText("ReportDialog.Examiner", reportInfo.examiners.stream().map(String::trim).collect(Collectors.joining(", "))))); + if (!StringUtils.isBlank(reportInfo.contact)) + casePanel.add(new JLabel(getLabelText("ReportDialog.contact", reportInfo.contact))); + if (!StringUtils.isBlank(reportInfo.caseNotes)) + casePanel.add(new JLabel(getLabelText("ReportDialog.caseNotes", reportInfo.caseNotes))); + if (!(reportInfo.evidences == null || reportInfo.evidences.isEmpty())) + casePanel.add(new JLabel(getLabelText("ReportDialog.Evidences", reportInfo.evidences.stream().sorted(comparing(ReportInfo.EvidenceDesc::getId)).map(ReportInfo.EvidenceDesc::getDesc).collect(Collectors.joining(", "))))); + return casePanel; + } + + private String getLabelText(String messageID, String text) { + return "" + Messages.get(messageID) + ": " + text + ""; + } + + private ReportInfo getCaseInfoFromPath(Path path) { + File caseInfoFile = Paths.get(path.toString(), "CaseInfo.json").toFile(); + ReportInfo reportInfo = null; + if (caseInfoFile.exists()) { + try { + reportInfo = new ReportInfo(); + reportInfo.readJsonInfoFile(caseInfoFile); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + return reportInfo; + } + +} diff --git a/iped-app/src/main/java/iped/app/home/opencase/CasesTableModel.java b/iped-app/src/main/java/iped/app/home/opencase/CasesTableModel.java new file mode 100644 index 0000000000..a0b949728f --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/opencase/CasesTableModel.java @@ -0,0 +1,66 @@ +package iped.app.home.opencase; + +import java.nio.file.Path; +import java.util.ArrayList; + +import javax.swing.JPanel; +import javax.swing.table.AbstractTableModel; + +/* + * @created 12/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import iped.app.ui.Messages; + +public class CasesTableModel extends AbstractTableModel { + + private final String[] COLUMN_NAME = { Messages.get("Home.OpenCase.CaseTableHeader") }; + private final ArrayList caseList; + + public CasesTableModel(ArrayList caseList) { + this.caseList = caseList == null ? new ArrayList() : caseList; + } + + @Override + public int getRowCount() { + return (caseList != null) ? caseList.size() : 0; + } + + @Override + public int getColumnCount() { + return COLUMN_NAME.length; + } + + @Override + public Class getColumnClass(int columnIndex) { + return JPanel.class; + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + switch (columnIndex) { + case 0: + return caseList.get(rowIndex); + default: + return ""; + } + } + + @Override + public boolean isCellEditable(int rowIndex, int columnIndex) { + return true; + } + + @Override + public String getColumnName(int columnIndex) { + return COLUMN_NAME[columnIndex]; + } + + @Override + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + + } + +} diff --git a/iped-app/src/main/java/iped/app/home/opencase/OpenCasePanel.java b/iped-app/src/main/java/iped/app/home/opencase/OpenCasePanel.java new file mode 100644 index 0000000000..6fc959502d --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/opencase/OpenCasePanel.java @@ -0,0 +1,226 @@ +package iped.app.home.opencase; +/* + * @created 21/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import java.awt.Color; +import java.awt.Dimension; +import java.io.File; +import java.io.FileWriter; +import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; + +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.filechooser.FileSystemView; + +import iped.app.home.DefaultPanel; +import iped.app.home.MainFrame; +import iped.app.home.MainFrameCardsNames; +import iped.app.home.newcase.tabs.caseinfo.CaseException; +import iped.app.home.newcase.tabs.caseinfo.CaseInfoManager; +import iped.app.home.processmanager.ProcessListener; +import iped.app.home.processmanager.ProcessManager; +import iped.app.home.style.StyleManager; +import iped.app.ui.Messages; + +/** + * A panel to manage IPED cases to be opened + */ +public class OpenCasePanel extends DefaultPanel implements ProcessListener { + + private JTable jTableCaseList; + private CasesTableModel casesTableModel; + private ArrayList caseList; + private JButton buttonOpen; + private JButton buttonCancel; + + public OpenCasePanel(MainFrame mainFrame) { + super(mainFrame); + } + + /** + * Prepare everything to be displayed + */ + @Override + protected void createAndShowGUI() { + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + this.add(createTitlePanel()); + this.add(createTableButtonsPanel()); + this.add(createFormPanel()); + this.add(createButtonsPanel()); + } + + /** + * Create a new JPanel instance containing the Page Title + * + * @return - JPanel containing the Page Title + */ + private JPanel createTitlePanel() { + JPanel panelTitle = new JPanel(); + panelTitle.setBackground(Color.white); + JLabel labelTitle = new JLabel(Messages.get("Home.OpenCase.OpenCase")); + labelTitle.setFont(StyleManager.getPageTitleFont()); + panelTitle.add(labelTitle); + return panelTitle; + } + + private JPanel createTableButtonsPanel() { + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS)); + buttonPanel.setBackground(Color.white); + JButton addCaseButton = new JButton(Messages.get("Home.OpenCase.AddCaseToList")); + addCaseButton.addActionListener(e -> { + JFileChooser fileChooserDestino = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory()); + fileChooserDestino.setDialogTitle(Messages.get("Home.OpenCase.SelectCaseFolder")); + fileChooserDestino.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + fileChooserDestino.setAcceptAllFileFilterUsed(false); + if (fileChooserDestino.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { + Path selectedCasePath = fileChooserDestino.getSelectedFile().toPath(); + try { + new CaseInfoManager().validateCasePath(selectedCasePath); + } catch (CaseException ex) { + JOptionPane.showMessageDialog(this, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); + ex.printStackTrace(); + return; + } + getCaseList().add(selectedCasePath); + casesTableModel.fireTableDataChanged(); + } + }); + buttonPanel.add(addCaseButton); + JButton removeCaseButton = new JButton(Messages.get("Home.OpenCase.RemoveCaseFromList")); + removeCaseButton.addActionListener(e -> { + if (jTableCaseList.getSelectedRow() > -1) { + caseList.remove(jTableCaseList.getSelectedRow()); + casesTableModel.fireTableDataChanged(); + jTableCaseList.doLayout(); + } + }); + buttonPanel.add(removeCaseButton); + return buttonPanel; + } + + /** + * Create a new JPanel instance containing all inputs + * + * @return JPanel - A JPanel containing all data input form itens + */ + private JPanel createFormPanel() { + JPanel panelForm = new JPanel(); + panelForm.setLayout(new BoxLayout(panelForm, BoxLayout.PAGE_AXIS)); + panelForm.setBackground(super.getCurrentBackGroundColor()); + panelForm.add(Box.createRigidArea(new Dimension(10, 10))); + setupCaseTables(panelForm); + return panelForm; + } + + /** + * Create and setup a JTable do manage all Evidences to be processed + * + * @param panel + * - A JPanel to add JTable + */ + private void setupCaseTables(JPanel panel) { + casesTableModel = new CasesTableModel(getCaseList()); + jTableCaseList = new JTable(casesTableModel); + jTableCaseList.setFillsViewportHeight(true); + jTableCaseList.setDefaultRenderer(JPanel.class, new CaseTableCellRender()); + StyleManager.setTableHeaderStyle(jTableCaseList); + panel.add(new JScrollPane(jTableCaseList)); + } + + public ArrayList getCaseList() { + if (caseList == null) + caseList = new ArrayList<>(); + return caseList; + } + + /** + * A JPanel containing "open" and "Cancel" buttons + * + * @return JPanel - a new JPanel instance containing the bottom page Button + */ + private JPanel createButtonsPanel() { + JPanel panelButtons = new JPanel(); + panelButtons.setBackground(Color.white); + buttonOpen = new JButton(Messages.get("Home.OpenCase.OpenAllCasesInTheList")); + buttonOpen.addActionListener(e -> this.openCases()); + buttonCancel = new JButton(Messages.get("Case.Cancel")); + buttonCancel.addActionListener(e -> mainFrame.showPanel(MainFrameCardsNames.HOME)); + panelButtons.add(buttonOpen); + panelButtons.add(buttonCancel); + return panelButtons; + } + + private void openCases() { + // If user do not choose any case, show message and stop execution + if (caseList == null || caseList.isEmpty()) { + JOptionPane.showMessageDialog(this, Messages.get("Home.OpenCase.EmptyCaseMessage"), Messages.get("Home.OpenCase.EmptyCaseMessageTitle"), JOptionPane.WARNING_MESSAGE); + return; + } + Thread t = new Thread(() -> { + ProcessManager pm = new ProcessManager(); + pm.addProcessListener(OpenCasePanel.this); + + // If user choose a single case, will open iped search single case + if (caseList.size() == 1) { + try { + pm.openSingleCase(caseList.get(0)); + } catch (Exception ex) { + ex.printStackTrace(); + JOptionPane.showMessageDialog(OpenCasePanel.this, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); + } + return; + } + + // Open iped search multicase mode + // first create on temp folder a txt file containing the cases to be opened + File multiCaseFile = Paths.get(System.getProperty("user.home"), ".iped", "multicasetemp.txt").toFile(); + try (FileWriter fileWriter = new FileWriter(multiCaseFile, StandardCharsets.UTF_8); PrintWriter printWriter = new PrintWriter(fileWriter)) { + for (Path currentPath : caseList) + printWriter.println(currentPath.toString()); + printWriter.close(); + fileWriter.close(); + pm.openMulticase(caseList.get(0), multiCaseFile); + } catch (Exception ex) { + ex.printStackTrace(); + JOptionPane.showMessageDialog(OpenCasePanel.this, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); + } + }); + t.start(); + } + + @Override + public void processStarted() { + + } + + @Override + public void processFinished() { + + } + + @Override + public void caseIsOpening() { + buttonOpen.setEnabled(false); + } + + @Override + public void caseWasClosed() { + buttonOpen.setEnabled(true); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/processmanager/IpedStartException.java b/iped-app/src/main/java/iped/app/home/processmanager/IpedStartException.java new file mode 100644 index 0000000000..af3cb437e1 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/processmanager/IpedStartException.java @@ -0,0 +1,16 @@ +package iped.app.home.processmanager;/* + * @created 21/12/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +public class IpedStartException extends Exception { + + public IpedStartException(String message) { + super(message); + } + + public IpedStartException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/iped-app/src/main/java/iped/app/home/processmanager/ProcessListener.java b/iped-app/src/main/java/iped/app/home/processmanager/ProcessListener.java new file mode 100644 index 0000000000..e7f9cdd197 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/processmanager/ProcessListener.java @@ -0,0 +1,17 @@ +package iped.app.home.processmanager;/* + * @created 22/12/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +public interface ProcessListener { + + void processStarted(); + + void processFinished(); + + void caseIsOpening(); + + void caseWasClosed(); + +} diff --git a/iped-app/src/main/java/iped/app/home/processmanager/ProcessManager.java b/iped-app/src/main/java/iped/app/home/processmanager/ProcessManager.java new file mode 100644 index 0000000000..8e8ac8794e --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/processmanager/ProcessManager.java @@ -0,0 +1,294 @@ +package iped.app.home.processmanager;/* + * @created 29/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; + +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; + +import org.apache.commons.lang3.StringUtils; + +import iped.app.home.newcase.model.Evidence; +import iped.app.home.newcase.model.IPEDProcess; +import iped.configuration.IConfigurationDirectory; +import iped.engine.util.Util; +import iped.exception.IPEDException; + +public class ProcessManager { + + private Process process; + private final ArrayList processListener = new ArrayList<>(); + + public ArrayList getEvidencesCommandList(ArrayList evidenceList) { + ArrayList commandArgs = new ArrayList<>(); + for (Evidence currentEvidence : evidenceList) { + commandArgs.add("-d"); + commandArgs.add("\"" + currentEvidence.getPath() + "\""); + + if ((currentEvidence.getAlias() != null) && (!currentEvidence.getAlias().trim().isEmpty())) { + commandArgs.add("-dname"); + commandArgs.add("\"" + currentEvidence.getAlias().trim() + "\""); + } + if ((currentEvidence.getTimezone() != null) && (!currentEvidence.getTimezone().trim().isEmpty())) { + commandArgs.add("-tz"); + commandArgs.add(currentEvidence.getTimezone()); + } + if ((currentEvidence.getPassword() != null) && (!currentEvidence.getPassword().trim().isEmpty())) { + commandArgs.add("-p"); + commandArgs.add("\"" + currentEvidence.getPassword() + "\""); + } + if ((currentEvidence.getBlocksize() != null) && (currentEvidence.getBlocksize() > 0)) { + commandArgs.add("-b"); + commandArgs.add(currentEvidence.getBlocksize().toString()); + } + } + return commandArgs; + } + + public ArrayList getCaseOutputCommand(Path caseOutput) { + ArrayList commandArgs = new ArrayList<>(); + commandArgs.add("-o"); + commandArgs.add("\"" + caseOutput.toString() + "\""); + return commandArgs; + } + + public ArrayList getProfileCommand(String profileName) { + ArrayList commandArgs = new ArrayList<>(); + if (StringUtils.isEmpty(profileName)) + return commandArgs; + commandArgs.add("-profile"); + commandArgs.add(profileName); + return commandArgs; + } + + public ArrayList getAsapParameter(IPEDProcess ipp) { + ArrayList commandArgs = new ArrayList<>(); + if (ipp != null && ipp.getAsapFile() != null && ipp.getAsapFile().toFile().exists()) { + commandArgs.add("-asap"); + commandArgs.add("\"" + ipp.getAsapFile().toAbsolutePath().toString() + "\""); + } + return commandArgs; + } + + public ArrayList getIpedSearchAppJarCommand(Path caseOutput) { + ArrayList cmds = new ArrayList<>(); + cmds.add("-jar"); + cmds.add(Paths.get(caseOutput.toString(), "iped", "lib", "iped-search-app.jar").toString()); + return cmds; + } + + public ArrayList getIpedJarCommand() { + ArrayList cmds = new ArrayList<>(); + cmds.add("-jar"); + cmds.add(Paths.get(System.getProperty(IConfigurationDirectory.IPED_APP_ROOT), "iped.jar").toString()); + return cmds; + } + + public String getJreBinCommand() { + String javaBin = "java"; + File embeddedJRE = Paths.get(getRootPath(), "jre").toFile(); + File javaHome = new File(System.getProperty("java.home")); + if (!javaHome.equals(embeddedJRE)) { + String warn = Util.getJavaVersionWarn(); + if (warn != null) { + System.err.println(warn); + } + } + if (org.apache.tika.utils.SystemUtils.IS_OS_WINDOWS) { + javaBin = Paths.get(javaHome.getPath(), "bin", "java.exe").toString(); + } + return javaBin; + } + + public static void validateCaseOutput(Path caseOutput) throws IPEDException { + boolean isExistsCase = Paths.get(caseOutput.toString(), "IPED-SearchApp.exe").toFile().exists(); + if (isExistsCase) { + // check if the existent case is finished, if yes the user cannot choose the + // continue options + boolean isCaseFinished = Paths.get(caseOutput.toString(), "iped", "data", "processing_finished").toFile().exists(); + if (isCaseFinished) + throw new IPEDException("There is already a finished case in the output directory"); + else + throw new IPEDException("There is already a unfinished case in the output directory"); + } + } + + private String getRootPath() { + String rootPath = null; + try { + URL url = ProcessManager.class.getProtectionDomain().getCodeSource().getLocation(); + if ("true".equals(System.getProperty("Debugging"))) { + rootPath = System.getProperty("user.dir"); + } else { + rootPath = new File(url.toURI()).getParent(); + // test for report generation from case folder + if (rootPath.endsWith("iped" + File.separator + "lib")) { //$NON-NLS-1$ //$NON-NLS-2$ + rootPath = new File(url.toURI()).getParentFile().getParent(); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return rootPath; + } + + public void openMulticase(Path firstCase, File multiCaseFile) { + ArrayList commandList = new ArrayList<>(); + commandList.add(getJreBinCommand()); + commandList.add("-jar"); + commandList.add(firstCase + "/iped/lib/iped-search-app.jar"); + commandList.add("-multicases"); + commandList.add(multiCaseFile.getPath()); + StringBuffer output = new StringBuffer(); + System.out.println(commandList); + startIpedSearchAppProcess(commandList, output); + } + + public void openSingleCase(Path casePath) { + ArrayList commandList = new ArrayList<>(); + commandList.add(getJreBinCommand()); + commandList.addAll(getIpedSearchAppJarCommand(casePath)); + StringBuffer output = new StringBuffer(); + startIpedSearchAppProcess(commandList, output); + } + + private void startIpedSearchAppProcess(ArrayList commandList, StringBuffer output) { + try { + System.out.println("IPED Search command: " + String.join(" ", commandList.toArray(new String[0]))); + process = Runtime.getRuntime().exec(commandList.toArray(new String[0])); + fireCaseIsOpening(); + readProcessOutput(process, output); + process.waitFor(); + if (process.exitValue() != 0) { + throw new Exception(output.toString()); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + fireCaseWasClosed(); + } + } + + public void startIpedProcess(IPEDProcess ipedProcess, JTextArea logTextArea) throws IpedStartException { + try { + ArrayList commandList = new ArrayList<>(); + if (org.apache.tika.utils.SystemUtils.IS_OS_WINDOWS) { + commandList.add(Paths.get(System.getProperty(IConfigurationDirectory.IPED_APP_ROOT), "iped.exe").toString()); + } else { + commandList.add(getJreBinCommand()); + commandList.addAll(getIpedJarCommand()); + } + commandList.addAll(getEvidencesCommandList(ipedProcess.getEvidenceList())); + commandList.addAll(getCaseOutputCommand(ipedProcess.getCaseOutputPath())); + commandList.addAll(getProfileCommand(ipedProcess.getProfile())); + commandList.addAll(ipedProcess.getOptionsAsList()); + commandList.addAll(getAsapParameter(ipedProcess)); + if (ipedProcess.getExistentCaseOption() != null) + commandList.add(ipedProcess.getExistentCaseOption().getCommand()); + System.out.println("IPED command: " + String.join(" ", commandList.toArray(new String[0]))); + process = Runtime.getRuntime().exec(commandList.toArray(new String[0])); + fireProcessStartListener(); + readProcessOutput(process, logTextArea); + // wait process finish + process.waitFor(); + int exitVal = process.exitValue(); + if (exitVal != 0) { + throw new IpedStartException(logTextArea.getText()); + } + } catch (final IOException | InterruptedException e) { + throw new IpedStartException("Exception on Iped start", e); + } finally { + fireProcessFinishedListener(); + } + } + + public void readProcessOutput(Process process, JTextArea logTextArea) throws IOException { + Runnable routput = new Runnable() { + @Override + public void run() { + try { + BufferedReader inputReader = new BufferedReader(new InputStreamReader(process.getInputStream())); + String line; + while ((line = inputReader.readLine()) != null) { + String finalLine = line; + SwingUtilities.invokeLater(new Runnable() { + public void run() { + logTextArea.append(finalLine + "\n"); + } + }); + } + } catch (Exception e) { + // TODO: handle exception + } + } + }; + Thread toutput = new Thread(routput); + toutput.start(); + Runnable rerror = new Runnable() { + @Override + public void run() { + try { + String line; + BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); + while ((line = errorReader.readLine()) != null) { + String finalLine = line; + SwingUtilities.invokeLater(new Runnable() { + public void run() { + logTextArea.append(finalLine + "\n"); + } + }); + } + } catch (Exception e) { + // TODO: handle exception + } + } + }; + Thread terror = new Thread(rerror); + terror.start(); + } + + public void readProcessOutput(Process process, StringBuffer outputText) throws IOException { + BufferedReader inputReader = new BufferedReader(new InputStreamReader(process.getInputStream())); + String line; + while ((line = inputReader.readLine()) != null) + outputText.append(line).append("\n"); + BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); + while ((line = errorReader.readLine()) != null) + outputText.append(line).append("\n"); + } + + private void fireProcessStartListener() { + for (ProcessListener listener : processListener) + listener.processStarted(); + } + + private void fireProcessFinishedListener() { + for (ProcessListener listener : processListener) + listener.processFinished(); + } + + public void fireCaseIsOpening() { + for (ProcessListener listener : processListener) + listener.caseIsOpening(); + } + + public void fireCaseWasClosed() { + for (ProcessListener listener : processListener) + listener.caseWasClosed(); + } + + public void addProcessListener(ProcessListener listener) { + processListener.add(listener); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/processmanager/ProcessManagerContainer.java b/iped-app/src/main/java/iped/app/home/processmanager/ProcessManagerContainer.java new file mode 100644 index 0000000000..04e92184c1 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/processmanager/ProcessManagerContainer.java @@ -0,0 +1,281 @@ +package iped.app.home.processmanager; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Image; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Objects; + +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; + +import org.apache.commons.lang3.exception.ExceptionUtils; + +/* + * @created 27/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ + +import iped.app.home.DefaultPanel; +import iped.app.home.MainFrame; +import iped.app.home.newcase.NewCaseContainerPanel; +import iped.app.home.newcase.model.IPEDProcess; +import iped.app.home.newcase.tabs.caseinfo.CaseInfoManager; +import iped.app.home.style.StyleManager; +import iped.app.ui.Messages; + +public class ProcessManagerContainer extends DefaultPanel implements ProcessListener { + + private IPEDProcess ipedProcess; + private JLabel labelTitle; + private ImageIcon startingIcon; + private ImageIcon errorIcon; + private ImageIcon successIcon; + private ImageIcon runningIcon; + private JLabel currentLabelIcon; + private JPanel errorOptionsButtonPanel; + private JPanel successOptionsButtonPanel; + private JPanel processRunningPanel; + private IpedStartException ipedStartException; + private JTextArea logTextArea; + private JButton buttonOpenCase; + + // Constants to change content view + private final String STARTING_PROCESS = "startingProcess"; + private final String RUNNING_PROCESS = "runningProcess"; + private final String FAILED_PROCESS = "failedProcess"; + private final String FINISHED_PROCESS = "finishedProcess"; + + public ProcessManagerContainer(MainFrame mainFrame) { + super(mainFrame); + } + + @Override + protected void createAndShowGUI() { + ipedProcess = NewCaseContainerPanel.getInstance().getIpedProcess(); + this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); + this.add(createTitlePanel()); + createLabelIcons(); + currentLabelIcon = new JLabel(startingIcon, JLabel.CENTER); + currentLabelIcon.setAlignmentX(Component.CENTER_ALIGNMENT); + this.add(currentLabelIcon); + this.add(createProcessRunningPanel()); + this.add(createErrorOptionsButtonpanel()); + this.add(createSuccessOptionsButtonpanel()); + } + + private JPanel createTitlePanel() { + JPanel panelTitle = new JPanel(); + panelTitle.setBackground(Color.white); + labelTitle = new JLabel(Messages.get("Home.ProcessManager.StartingProcess")); + labelTitle.setFont(StyleManager.getPageTitleFont()); + panelTitle.add(labelTitle); + return panelTitle; + } + + private void createLabelIcons() { + startingIcon = createNewButtonIcon("plug-in.png"); + runningIcon = createNewButtonIcon("pluged-in.png"); + errorIcon = createNewButtonIcon("plug_error.png"); + successIcon = createNewButtonIcon("success.png"); + } + + private JPanel createProcessRunningPanel() { + processRunningPanel = new JPanel(); + processRunningPanel.setLayout(new BorderLayout()); + processRunningPanel.setAlignmentX(Component.CENTER_ALIGNMENT); + processRunningPanel.setBackground(super.getCurrentBackGroundColor()); + logTextArea = new JTextArea(); + logTextArea.setMinimumSize(new Dimension(700, 600)); + logTextArea.setPreferredSize(new Dimension(700, 600)); + logTextArea.setMaximumSize(new Dimension(Short.MAX_VALUE, Short.MAX_VALUE)); + logTextArea.setEditable(false); + logTextArea.setBorder(BorderFactory.createLineBorder(Color.black, 1)); + processRunningPanel.add(new JScrollPane(logTextArea), BorderLayout.CENTER); + processRunningPanel.setVisible(false); + return processRunningPanel; + } + + private JPanel createErrorOptionsButtonpanel() { + errorOptionsButtonPanel = new JPanel(); + errorOptionsButtonPanel.setAlignmentX(Component.CENTER_ALIGNMENT); + errorOptionsButtonPanel.setBackground(super.getCurrentBackGroundColor()); + JButton buttonBack = new JButton(Messages.get("Home.ProcessManager.BackToCaseInfo")); + buttonBack.addActionListener(e -> { + NewCaseContainerPanel.getInstance().goToPreviousTab(); + }); + errorOptionsButtonPanel.add(buttonBack); + JButton buttonShowLog = new JButton(Messages.get("Home.ProcessManager.ShowTerminalLog")); + buttonShowLog.addActionListener(e -> { + if (ipedStartException != null) { + JTextArea textArea = new JTextArea(); + textArea.setText(ExceptionUtils.getStackTrace(ipedStartException)); + JOptionPane.showMessageDialog(this, new JScrollPane(textArea), ipedStartException.getMessage(), JOptionPane.PLAIN_MESSAGE); + } + }); + errorOptionsButtonPanel.add(buttonShowLog); + errorOptionsButtonPanel.setVisible(false); + return errorOptionsButtonPanel; + } + + private JPanel createSuccessOptionsButtonpanel() { + successOptionsButtonPanel = new JPanel(); + successOptionsButtonPanel.setAlignmentX(Component.CENTER_ALIGNMENT); + successOptionsButtonPanel.setBackground(super.getCurrentBackGroundColor()); + + JButton buttonBackCase = new JButton(Messages.get("Home.ProcessManager.BackToCaseInfo")); + buttonBackCase.addActionListener(e -> { + NewCaseContainerPanel.getInstance().goToPreviousTab(); + }); + successOptionsButtonPanel.add(buttonBackCase); + + buttonOpenCase = new JButton(Messages.get("Home.ProcessManager.OpenCase")); + buttonOpenCase.addActionListener(e -> { + Thread t = new Thread(() -> { + ProcessManager pm = new ProcessManager(); + pm.addProcessListener(ProcessManagerContainer.this); + pm.openSingleCase(ipedProcess.getCaseOutputPath()); + }); + t.start(); + }); + successOptionsButtonPanel.add(buttonOpenCase); + + JButton buttonShowLog = new JButton(Messages.get("Home.ProcessManager.ShowTerminalLog")); + buttonShowLog.addActionListener(e -> JOptionPane.showMessageDialog(this, new JScrollPane(logTextArea), Messages.get("Home.ProcessManager.TerminalLog"), JOptionPane.PLAIN_MESSAGE)); + successOptionsButtonPanel.add(buttonShowLog); + + JButton buttonExit = new JButton(Messages.get("Home.ProcessManager.ExitApplication")); + buttonExit.addActionListener(e -> System.exit(0)); + successOptionsButtonPanel.add(buttonExit); + + successOptionsButtonPanel.setVisible(false); + return successOptionsButtonPanel; + } + + private void saveCaseInfoJsonOnCaseOutputPath() { + CaseInfoManager ciManager = new CaseInfoManager(); + ipedProcess.getEvidenceList(); + // Populate caseinfo materials with evidences info + ciManager.castEvidenceListToReportInfo(ipedProcess.getReportInfo(), ipedProcess.getEvidenceList()); + // Save the CaseInfo.json on case output + Path caseinfoPath = Paths.get(ipedProcess.getCaseOutputPath().toString(), "CaseInfo.json"); + ipedProcess.getReportInfo().saveJsonInfoFile(caseinfoPath.toFile()); + // ipedProcess.addOptionValue("-asap", + // caseinfoPath.toAbsolutePath().toString()); + ipedProcess.setAsapFile(caseinfoPath); + } + + public void startProcess() { + switchPanelTo(STARTING_PROCESS); + saveCaseInfoJsonOnCaseOutputPath(); + + Thread t = new Thread(() -> { + try { + // After complete the execution the user can back to case info and start the + // process again, so wee need to clean the previous log + logTextArea.setText(""); + ProcessManager processManager = new ProcessManager(); + processManager.addProcessListener(ProcessManagerContainer.this); + processManager.startIpedProcess(ipedProcess, logTextArea); + } catch (IpedStartException e) { + ipedStartException = e; + switchPanelTo(FAILED_PROCESS); + e.printStackTrace(); + } + }); + t.start(); + } + + private void switchPanelTo(String panelName) { + switch (panelName) { + case STARTING_PROCESS: { + labelTitle.setText(Messages.get("Home.ProcessManager.StartingProcess")); + currentLabelIcon.setIcon(startingIcon); + currentLabelIcon.setVisible(true); + processRunningPanel.setVisible(false); + errorOptionsButtonPanel.setVisible(false); + successOptionsButtonPanel.setVisible(false); + break; + } + case RUNNING_PROCESS: { + labelTitle.setText(Messages.get("Home.ProcessManager.ProcessRunning")); + currentLabelIcon.setIcon(runningIcon); + currentLabelIcon.setVisible(false); + processRunningPanel.setVisible(true); + errorOptionsButtonPanel.setVisible(false); + successOptionsButtonPanel.setVisible(false); + break; + } + case FAILED_PROCESS: { + labelTitle.setText(Messages.get("Home.ProcessManager.ProcessFailed")); + currentLabelIcon.setIcon(errorIcon); + currentLabelIcon.setVisible(true); + processRunningPanel.setVisible(false); + errorOptionsButtonPanel.setVisible(true); + successOptionsButtonPanel.setVisible(false); + break; + } + case FINISHED_PROCESS: { + labelTitle.setText(Messages.get("Home.ProcessManager.ProcessFinished")); + currentLabelIcon.setIcon(successIcon); + currentLabelIcon.setVisible(true); + processRunningPanel.setVisible(false); + errorOptionsButtonPanel.setVisible(false); + successOptionsButtonPanel.setVisible(true); + break; + } + } + } + + private ImageIcon createNewButtonIcon(String imageFilename) { + Dimension iconDimension = new Dimension(400, 400); + ImageIcon icon = new ImageIcon(Objects.requireNonNull(getClass().getResource(imageFilename))); + Image resizedImage = icon.getImage().getScaledInstance(iconDimension.width, iconDimension.height, java.awt.Image.SCALE_SMOOTH); + return new ImageIcon(resizedImage); + } + + /** + * This method will be fired by ProcessManager when Iped process start + */ + @Override + public void processStarted() { + try { + Thread.sleep(3000); + switchPanelTo(RUNNING_PROCESS); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } + + /** + * This method will be fired by ProcessManager when Iped process finish + */ + @Override + public void processFinished() { + switchPanelTo(FINISHED_PROCESS); + } + + @Override + public void caseIsOpening() { + buttonOpenCase.setEnabled(false); + buttonOpenCase.setText(Messages.get("Home.ProcessManager.OpenCaseMsg")); + } + + @Override + public void caseWasClosed() { + buttonOpenCase.setEnabled(true); + buttonOpenCase.setText(Messages.get("Home.ProcessManager.OpenCase")); + } +} diff --git a/iped-app/src/main/java/iped/app/home/style/StyleManager.java b/iped-app/src/main/java/iped/app/home/style/StyleManager.java new file mode 100644 index 0000000000..cbea92346d --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/style/StyleManager.java @@ -0,0 +1,57 @@ +package iped.app.home.style; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Insets; + +/* + * @created 15/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ +import javax.swing.JTable; +import javax.swing.UIManager; +import javax.swing.border.Border; + +public class StyleManager { + + public static Font getPageTitleFont() { + return new Font("Arial Bold", Font.PLAIN, 28); + } + + public static Font getHomeButtonFont() { + return new Font("Arial Bold", Font.PLAIN, 20); + } + + public static Font getTableHeaderFont() { + return new Font("Arial Bold", Font.PLAIN, 12); + } + + public static Insets getDefaultPanelInsets() { + return new Insets(20, 20, 20, 20); + } + + public static void setTableHeaderStyle(JTable table) { + if (table == null) + return; + + table.getTableHeader().setBackground(new Color(219, 221, 226)); + table.getTableHeader().setPreferredSize(new Dimension(table.getTableHeader().getWidth(), 30)); + table.getTableHeader().setFont(StyleManager.getTableHeaderFont()); + + } + + public static Color getColumnRowSelectedBackground() { + return new Color(57, 105, 138); + } + + public static Color getColumnRowUnSelectedBackground(int row) { + return (row % 2 == 0) ? Color.WHITE : new Color(242, 242, 242); + } + + public static Border getColumnRowFocusBorder() { + return UIManager.getBorder("Table.focusCellHighlightBorder"); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/utils/CasePathManager.java b/iped-app/src/main/java/iped/app/home/utils/CasePathManager.java new file mode 100644 index 0000000000..587ec062f0 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/utils/CasePathManager.java @@ -0,0 +1,70 @@ +package iped.app.home.utils; + +import java.io.File; +import java.net.URISyntaxException; +import java.net.URL; + +import iped.app.home.MainFrame; +import iped.data.IIPEDSource; +import iped.engine.config.LocalConfig; +import iped.io.URLUtil; + +/* + * @created 22/11/2022 + * @project IPED + * @author Thiago S. Figueiredo + */ +public class CasePathManager { + + private static CasePathManager casePathManager; + private final File testPath = null; // = new + // File("/home/patrick.pdb/ipedtimeline-workspace/iped-parent/target/release/iped-4.1-snapshot"); + // //new File(""); + private File rootPath; + private File libDir; + static String IPED_MODULE_DIR = IIPEDSource.MODULE_DIR; + + private CasePathManager() { + try { + detectCasePath(); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + } + + public static CasePathManager getInstance() { + if (casePathManager == null) + casePathManager = new CasePathManager(); + return casePathManager; + } + + private void detectCasePath() throws URISyntaxException { + if (testPath != null) { + rootPath = testPath; + } else { + URL url = URLUtil.getURL(MainFrame.class); + rootPath = new File(url.toURI()).getParentFile(); + if (rootPath.getName().equals("lib")) { + rootPath = rootPath.getParentFile(); + } + } + libDir = new File(rootPath, "lib"); + } + + public File getCasePath() { + return rootPath; + } + + public File getLibDir() { + return libDir; + } + + public File getConfigPath() { + return rootPath; + } + + public File getLocalConfigFile() { + return new File(rootPath, LocalConfig.CONFIG_FILE); + } + +} diff --git a/iped-app/src/main/java/iped/app/home/utils/JTextAreaTabFocus.java b/iped-app/src/main/java/iped/app/home/utils/JTextAreaTabFocus.java new file mode 100644 index 0000000000..9c5a48f509 --- /dev/null +++ b/iped-app/src/main/java/iped/app/home/utils/JTextAreaTabFocus.java @@ -0,0 +1,19 @@ +package iped.app.home.utils; + +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; + +public class JTextAreaTabFocus extends KeyAdapter { + + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_TAB) { + if (e.getModifiersEx() > 0) { + e.getComponent().transferFocusBackward(); + } else { + e.getComponent().transferFocus(); + } + e.consume(); + } + } + +} diff --git a/iped-app/src/main/java/iped/app/processing/Main.java b/iped-app/src/main/java/iped/app/processing/Main.java index a4341fb1a4..41177f8957 100644 --- a/iped-app/src/main/java/iped/app/processing/Main.java +++ b/iped-app/src/main/java/iped/app/processing/Main.java @@ -35,6 +35,7 @@ import iped.app.ui.utils.UiScale; import iped.engine.Version; import iped.engine.config.Configuration; +import iped.engine.config.ProfileManager; import iped.engine.core.Manager; import iped.engine.localization.Messages; import iped.engine.util.UIPropertyListenerProvider; @@ -126,11 +127,19 @@ public Main(List reports, File output, String configPath, File logFile, Fi System.setProperty(OCRParser.SUBSET_TO_OCR, list); } + + /** + * Contrutor utilizado pela interface de configuração + */ + public Main() { + lastInstance = this; + } + /** * Contrutor utilizado pela execução via linha de comando */ public Main(String[] args, boolean decodeArgs) { - lastInstance = this; + this(); cmdLineParams = new CmdLineArgsImpl(); if (decodeArgs) { cmdLineParams.takeArgs(args); @@ -163,9 +172,15 @@ public void setConfigPath() throws Exception { configPath = rootPath; - String profile = cmdLineParams.getProfile(); - if (profile != null) { - configPath = new File(configPath, Configuration.PROFILES_DIR + "/" + profile).getAbsolutePath(); //$NON-NLS-1$ + if(cmdLineParams!=null) { + String profile = cmdLineParams.getProfile(); + if (profile != null) { + File configFile = new File(configPath, Configuration.PROFILES_DIR + "/" + profile); + if(!configFile.exists()) { + configFile = new File(configPath, Configuration.PROFILES_DIR + "/" + profile + ProfileManager.PROFILE_EXTENSION); + } + configPath = configFile.getAbsolutePath(); //$NON-NLS-1$ + } } if (!new File(configPath).exists()) throw new IPEDException("Profile not found " + configPath); //$NON-NLS-1$ diff --git a/iped-app/src/main/java/iped/app/ui/CategoryMimeTreeModel.java b/iped-app/src/main/java/iped/app/ui/CategoryMimeTreeModel.java new file mode 100644 index 0000000000..e8ed2e13a4 --- /dev/null +++ b/iped-app/src/main/java/iped/app/ui/CategoryMimeTreeModel.java @@ -0,0 +1,150 @@ +package iped.app.ui; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; + +import javax.swing.event.TreeModelListener; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreePath; + +import iped.engine.data.Category; + +public class CategoryMimeTreeModel implements TreeModel{ + private static final String ROOT = "ROOT"; + public static String rootName = Messages.getString("CategoryTreeModel.RootName"); //$NON-NLS-1$ + public static String uncategorizableName = Messages.getString("CategoryTreeModel.Uncategorizables"); //$NON-NLS-1$ + public boolean toShowUncategorizable=false; + + public Category rootCategory; + private boolean toShowMimetypes=false; + + private List listeners = new ArrayList(); + + public CategoryMimeTreeModel(Category root) { + this.rootCategory = root; + this.rootCategory.setName(rootName); + } + + public CategoryMimeTreeModel(Category root, boolean toShowMimetypes) { + this.rootCategory = root; + this.rootCategory.setName(rootName); + this.toShowMimetypes = toShowMimetypes; + } + + public void hideCategories(Predicate isToHide) { + hideCategories(rootCategory, isToHide); + } + + private void hideCategories(Category cat, Predicate isToHide) { + if(isToHide.test(cat)) { + if(cat.getParent()!=null) { + cat.getParent().getChildren().remove(cat); + } + }else { + Category[] cats = cat.getChildren().toArray(new Category[0]); + for (int i=0;i= subCatsListSize) { + index -= subCatsListSize; + return ((Category) parent).getMimes().get(index); + }else { + return ((Category) parent).getChildren().toArray()[index]; + } + }else { + return ((Category) parent).getChildren().toArray()[index]; + } + } + + @Override + public int getChildCount(Object parent) { + if(parent==ROOT) { + return 2;//uncategorizables and categories + } + if(parent instanceof String) { + return 0; + } + int size = ((Category) parent).getChildren().size(); + + if(toShowMimetypes) { + size+=((Category) parent).getMimes().size(); + } + return size; + } + + @Override + public boolean isLeaf(Object node) { + if(node==ROOT) { + return false; + } + if(node instanceof String) { + return true; + } + return getChildCount(node) == 0; + } + + @Override + public void valueForPathChanged(TreePath path, Object newValue) { + ((Category)path.getLastPathComponent()).setName(newValue.toString()); + } + + @Override + public int getIndexOfChild(Object parent, Object child) { + if (parent == null || child == null) + return -1; + return ((Category) parent).getIndexOfChild((Category) child); + } + + @Override + public void addTreeModelListener(TreeModelListener l) { + listeners.add(l); + + } + + @Override + public void removeTreeModelListener(TreeModelListener l) { + listeners.remove(l); + + } + + public void updateModel() { + + + } + + public boolean isToShowUncategorizable() { + return toShowUncategorizable; + } + + public void setToShowUncategorizable(boolean showUncategorizable) { + this.toShowUncategorizable = showUncategorizable; + } + +} diff --git a/iped-app/src/main/java/iped/app/ui/IconManager.java b/iped-app/src/main/java/iped/app/ui/IconManager.java index 7a24107fa5..f0b430c44f 100644 --- a/iped-app/src/main/java/iped/app/ui/IconManager.java +++ b/iped-app/src/main/java/iped/app/ui/IconManager.java @@ -19,6 +19,7 @@ package iped.app.ui; import java.awt.image.BufferedImage; +import java.io.File; import java.net.URL; import java.security.CodeSource; import java.util.HashMap; @@ -28,6 +29,7 @@ import javax.imageio.ImageIO; import javax.swing.Icon; +import javax.swing.ImageIcon; import iped.app.ui.utils.UiIconSize; import iped.utils.QualityIcon; @@ -73,18 +75,35 @@ private static Map loadIconsFromJar(String iconPath, int si CodeSource src = IconManager.class.getProtectionDomain().getCodeSource(); if (src != null) { URL jar = src.getLocation(); - try (ZipInputStream zip = new ZipInputStream(jar.openStream())) { - while (true) { - ZipEntry e = zip.getNextEntry(); - if (e == null) { - break; + File f = new File(jar.getPath()); + if(f.isDirectory()) { + File iconRoot = new File(f, IconManager.class.getName().toString().replace(".", separator) + .replace(IconManager.class.getSimpleName(), "") + iconPath + separator); + File[] icons = iconRoot.listFiles(); + for (int i = 0; i < icons.length; i++) { + if(icons[i].getName().endsWith(ICON_EXTENSION)) { + BufferedImage img = ImageIO.read(icons[i]); + map.put(icons[i].getName().replace(ICON_EXTENSION, "").toLowerCase(), + new QualityIcon(new ImageIcon(img), size)); } - String path = IconManager.class.getName().toString().replace(".", separator).replace(IconManager.class.getSimpleName(), "") + iconPath + separator; - String nameWithPath = e.getName(); - String name = nameWithPath.replace(path, ""); - if (nameWithPath.startsWith(path) && name.toLowerCase().endsWith(ICON_EXTENSION)) { - BufferedImage img = ImageIO.read(IconManager.class.getResource(iconPath + separator + name)); - map.put(name.replace(ICON_EXTENSION, "").toLowerCase(), new QualityIcon(img, size)); + } + } else { + try (ZipInputStream zip = new ZipInputStream(jar.openStream())) { + while (true) { + ZipEntry e = zip.getNextEntry(); + if (e == null) { + break; + } + String path = IconManager.class.getName().toString().replace(".", separator) + .replace(IconManager.class.getSimpleName(), "") + iconPath + separator; + String nameWithPath = e.getName(); + String name = nameWithPath.replace(path, ""); + if (nameWithPath.startsWith(path) && name.toLowerCase().endsWith(ICON_EXTENSION)) { + BufferedImage img = ImageIO + .read(IconManager.class.getResource(iconPath + separator + name)); + map.put(name.replace(ICON_EXTENSION, "").toLowerCase(), + new QualityIcon(new ImageIcon(img), size)); + } } } } diff --git a/iped-app/src/main/java/iped/app/ui/ReportDialog.java b/iped-app/src/main/java/iped/app/ui/ReportDialog.java index f325003531..c340066a13 100644 --- a/iped-app/src/main/java/iped/app/ui/ReportDialog.java +++ b/iped-app/src/main/java/iped/app/ui/ReportDialog.java @@ -49,7 +49,7 @@ public class ReportDialog implements ActionListener, TableModelListener { private static Logger logger = LoggerFactory.getLogger(ReportDialog.class); JDialog dialog = new JDialog(App.get()); - ReportInfoDialog caseInfo = new ReportInfoDialog(dialog); + ReportInfoDialog reportInfoDialog = new ReportInfoDialog(dialog); JLabel top = new JLabel(Messages.getString("ReportDialog.ChooseLabel")); //$NON-NLS-1$ Object[] header = { Boolean.FALSE, Messages.getString("ReportDialog.TableHeader1"), //$NON-NLS-1$ //$NON-NLS-2$ Messages.getString("ReportDialog.TableHeader2") }; //$NON-NLS-1$ @@ -157,8 +157,8 @@ public void updateList() { table.getColumnModel().getColumn(0).setHeaderRenderer(new DefaultTableCellRenderer() { - private static final long serialVersionUID = 1L; - private boolean listenerAdded = false; + private static final long serialVersionUID = 1L; + private boolean listenerAdded = false; @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) { @@ -195,7 +195,6 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole } private class TableModel extends DefaultTableModel { - private static final long serialVersionUID = 1L; TableModel(Object[][] data, Object[] columnNames) { @@ -229,7 +228,7 @@ public void actionPerformed(ActionEvent e) { } if (e.getSource() == infoButton) { - caseInfo.setVisible(true); + reportInfoDialog.setVisible(true); } if (e.getSource() == keywordsButton) { @@ -264,9 +263,9 @@ private boolean isInputOK() { private void generateReport() { - String caseInfo; + String tempReportInfoFilePath; try { - caseInfo = this.caseInfo.getReportInfo().writeReportInfoFile().getAbsolutePath(); + tempReportInfoFilePath = this.reportInfoDialog.getReportInfo().writeReportInfoFile().getAbsolutePath(); } catch (IOException e1) { e1.printStackTrace(); JOptionPane.showMessageDialog(null, Messages.getString("ReportDialog.ReportError"), //$NON-NLS-1$ @@ -295,8 +294,8 @@ private void generateReport() { Bootstrap.class.getCanonicalName(), "-d", input.getAbsolutePath(), //$NON-NLS-1$ "-o", output)); //$NON-NLS-1$ - if (!caseInfo.isEmpty()) - cmd.addAll(Arrays.asList("-asap", caseInfo)); //$NON-NLS-1$ + if (!tempReportInfoFilePath.isEmpty()) + cmd.addAll(Arrays.asList("-asap", tempReportInfoFilePath)); //$NON-NLS-1$ if (!keywords.isEmpty()) cmd.addAll(Arrays.asList("-l", keywords)); //$NON-NLS-1$ diff --git a/iped-app/src/main/java/iped/app/ui/ReportInfoDialog.java b/iped-app/src/main/java/iped/app/ui/ReportInfoDialog.java index c0941e727c..8108d3ea13 100644 --- a/iped-app/src/main/java/iped/app/ui/ReportInfoDialog.java +++ b/iped-app/src/main/java/iped/app/ui/ReportInfoDialog.java @@ -24,7 +24,7 @@ public class ReportInfoDialog extends JDialog implements ActionListener { /** - * + * */ private static final long serialVersionUID = 1L; @@ -44,6 +44,10 @@ public class ReportInfoDialog extends JDialog implements ActionListener { JTextField rLabNumber = new JTextField(); JTextField rLabDate = new JTextField(); JTextArea rEvidences = new JTextArea(); + JTextArea rInvestigatedNames = new JTextArea(); + JTextField rOrganizationName = new JTextField(); + JTextField rContact = new JTextField(); + JTextArea rCaseNotes = new JTextArea(); private GridBagConstraints getGridBagConstraints(int x, int y, int width, int height) { GridBagConstraints c = new GridBagConstraints(); @@ -74,57 +78,78 @@ public ReportInfoDialog(JDialog owner) { JPanel panel = new JPanel(new GridBagLayout()); + int lineNumber = 0; JLabel loadFile = new JLabel(); loadFile.setText(Messages.getString("ReportDialog.LoadInfo")); - panel.add(loadFile, getGridBagConstraints(0, 0, 2, 1)); - panel.add(infoButton, getGridBagConstraints(2, 0, 1, 1)); + panel.add(loadFile, getGridBagConstraints(0, lineNumber, 2, 1)); + panel.add(infoButton, getGridBagConstraints(2, lineNumber++, 1, 1)); JLabel num = new JLabel(Messages.getString("ReportDialog.ReportNum")); //$NON-NLS-1$ - panel.add(num, getGridBagConstraints(0, 1, 1, 1)); - panel.add(rNumber, getGridBagConstraints(1, 1, 2, 1)); + panel.add(num, getGridBagConstraints(0, lineNumber, 1, 1)); + panel.add(rNumber, getGridBagConstraints(1, lineNumber++, 2, 1)); JLabel date = new JLabel(Messages.getString("ReportDialog.ReportDate")); //$NON-NLS-1$ - panel.add(date, getGridBagConstraints(0, 2, 1, 1)); - panel.add(rDate, getGridBagConstraints(1, 2, 2, 1)); + panel.add(date, getGridBagConstraints(0, lineNumber, 1, 1)); + panel.add(rDate, getGridBagConstraints(1, lineNumber++, 2, 1)); JLabel title = new JLabel(Messages.getString("ReportDialog.ReportTitle")); //$NON-NLS-1$ - panel.add(title, getGridBagConstraints(0, 3, 1, 1)); - panel.add(rTitle, getGridBagConstraints(1, 3, 2, 1)); + panel.add(title, getGridBagConstraints(0, lineNumber, 1, 1)); + panel.add(rTitle, getGridBagConstraints(1, lineNumber++, 2, 1)); JLabel examiner = new JLabel(Messages.getString("ReportDialog.Examiner")); //$NON-NLS-1$ - panel.add(examiner, getGridBagConstraints(0, 4, 1, 1)); - panel.add(rExaminer, getGridBagConstraints(1, 4, 2, 1)); + panel.add(examiner, getGridBagConstraints(0, lineNumber, 1, 1)); + panel.add(rExaminer, getGridBagConstraints(1, lineNumber++, 2, 1)); JLabel ipl = new JLabel(Messages.getString("ReportDialog.Investigation")); //$NON-NLS-1$ - panel.add(ipl, getGridBagConstraints(0, 5, 1, 1)); - panel.add(rCaseNumber, getGridBagConstraints(1, 5, 2, 1)); + panel.add(ipl, getGridBagConstraints(0, lineNumber, 1, 1)); + panel.add(rCaseNumber, getGridBagConstraints(1, lineNumber++, 2, 1)); JLabel request = new JLabel(Messages.getString("ReportDialog.Request")); //$NON-NLS-1$ - panel.add(request, getGridBagConstraints(0, 6, 1, 1)); - panel.add(rRequestForm, getGridBagConstraints(1, 6, 2, 1)); + panel.add(request, getGridBagConstraints(0, lineNumber, 1, 1)); + panel.add(rRequestForm, getGridBagConstraints(1, lineNumber++, 2, 1)); JLabel requestDate = new JLabel(Messages.getString("ReportDialog.RequestDate")); //$NON-NLS-1$ - panel.add(requestDate, getGridBagConstraints(0, 7, 1, 1)); - panel.add(rRequestDate, getGridBagConstraints(1, 7, 2, 1)); + panel.add(requestDate, getGridBagConstraints(0, lineNumber, 1, 1)); + panel.add(rRequestDate, getGridBagConstraints(1, lineNumber++, 2, 1)); JLabel requester = new JLabel(Messages.getString("ReportDialog.Requester")); //$NON-NLS-1$ - panel.add(requester, getGridBagConstraints(0, 8, 1, 1)); - panel.add(rRequester, getGridBagConstraints(1, 8, 2, 1)); + panel.add(requester, getGridBagConstraints(0, lineNumber, 1, 1)); + panel.add(rRequester, getGridBagConstraints(1, lineNumber++, 2, 1)); JLabel record = new JLabel(Messages.getString("ReportDialog.Record")); //$NON-NLS-1$ - panel.add(record, getGridBagConstraints(0, 9, 1, 1)); - panel.add(rLabNumber, getGridBagConstraints(1, 9, 2, 1)); + panel.add(record, getGridBagConstraints(0, lineNumber, 1, 1)); + panel.add(rLabNumber, getGridBagConstraints(1, lineNumber++, 2, 1)); JLabel recordDate = new JLabel(Messages.getString("ReportDialog.RecordDate")); //$NON-NLS-1$ - panel.add(recordDate, getGridBagConstraints(0, 10, 1, 1)); - panel.add(rLabDate, getGridBagConstraints(1, 10, 2, 1)); + panel.add(recordDate, getGridBagConstraints(0, lineNumber, 1, 1)); + panel.add(rLabDate, getGridBagConstraints(1, lineNumber++, 2, 1)); JLabel evidences = new JLabel(Messages.getString("ReportDialog.Evidences")); //$NON-NLS-1$ - panel.add(evidences, getGridBagConstraints(0, 11, 1, 1)); - panel.add(rEvidences, getGridBagConstraints(1, 11, 2, 2)); + panel.add(evidences, getGridBagConstraints(0, lineNumber, 1, 1)); + panel.add(rEvidences, getGridBagConstraints(1, lineNumber++, 2, 2)); rEvidences.setLineWrap(true); rEvidences.setWrapStyleWord(true); + JLabel investigatedNames = new JLabel(Messages.getString("ReportDialog.InvestigatedNames")); //$NON-NLS-1$ + panel.add(investigatedNames, getGridBagConstraints(0, ++lineNumber, 1, 1)); + panel.add(rInvestigatedNames, getGridBagConstraints(1, lineNumber++, 2, 2)); + rInvestigatedNames.setLineWrap(true); + rInvestigatedNames.setWrapStyleWord(true); + + JLabel organizationName = new JLabel(Messages.getString("ReportDialog.organizationName")); //$NON-NLS-1$ + panel.add(organizationName, getGridBagConstraints(0, ++lineNumber, 1, 1)); + panel.add(rOrganizationName, getGridBagConstraints(1, lineNumber++, 2, 1)); + + JLabel contact = new JLabel(Messages.getString("ReportDialog.contact")); //$NON-NLS-1$ + panel.add(contact, getGridBagConstraints(0, lineNumber, 1, 1)); + panel.add(rContact, getGridBagConstraints(1, lineNumber++, 2, 1)); + + JLabel caseNotes = new JLabel(Messages.getString("ReportDialog.caseNotes")); //$NON-NLS-1$ + panel.add(caseNotes, getGridBagConstraints(0, ++lineNumber, 1, 1)); + panel.add(rCaseNotes, getGridBagConstraints(1, lineNumber++, 2, 2)); + rCaseNotes.setLineWrap(true); + rCaseNotes.setWrapStyleWord(true); + fullPanel.add(panel, BorderLayout.CENTER); JPanel bPanel = new JPanel(new BorderLayout()); bPanel.add(okButton, BorderLayout.EAST); @@ -195,6 +220,10 @@ private void populateTextFields(ReportInfo info) { rLabNumber.setText(info.labCaseNumber); rLabDate.setText(info.labCaseDate); rEvidences.setText(info.getEvidenceDescHtml()); + rInvestigatedNames.setText(info.getInvestigatedNameText()); + rOrganizationName.setText(info.organizationName); + rContact.setText(info.contact); + rCaseNotes.setText(info.caseNotes); } private void loadTextFields() { diff --git a/iped-app/src/main/java/iped/app/ui/controls/ConfigCheckBoxTreeCellRenderer.java b/iped-app/src/main/java/iped/app/ui/controls/ConfigCheckBoxTreeCellRenderer.java new file mode 100644 index 0000000000..038466e950 --- /dev/null +++ b/iped-app/src/main/java/iped/app/ui/controls/ConfigCheckBoxTreeCellRenderer.java @@ -0,0 +1,105 @@ +package iped.app.ui.controls; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.util.function.Predicate; + +import javax.swing.AbstractButton; +import javax.swing.Icon; +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTree; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.TreeCellRenderer; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; + +import org.apache.tika.mime.MediaType; + +import iped.app.ui.IconManager; +import iped.engine.data.Category; + +public class ConfigCheckBoxTreeCellRenderer implements TreeCellRenderer { + JCheckBox checkbox = new JCheckBox(); + JLabel label = new JLabel(); + private JTree tree; + Predicate checkedPredicate; + Predicate visiblePredicate; + private JPanel ckPanel = new JPanel(new BorderLayout()); + + public ConfigCheckBoxTreeCellRenderer(JTree tree, Predicate checkedPredicate) { + this.tree = tree; + this.checkedPredicate = checkedPredicate; + + TreeSelectionModel selModel = tree.getSelectionModel(); + + selModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); + + selModel.addTreeSelectionListener(new TreeSelectionListener() { + @Override + public void valueChanged(TreeSelectionEvent e) { + if (e.isAddedPath()) { + Object value = e.getNewLeadSelectionPath().getLastPathComponent(); + if (visiblePredicate == null || visiblePredicate.test(value)) { + checkbox.setSelected(!checkbox.isSelected()); + tree.getSelectionModel().clearSelection(); + } + } + } + }); + + ckPanel.setBackground(Color.white); + ckPanel.add(checkbox, BorderLayout.WEST); + ckPanel.add(label, BorderLayout.CENTER); + } + + public ConfigCheckBoxTreeCellRenderer(JTree tree, Predicate checkedPredicate, + Predicate visiblePredicate) { + this(tree, checkedPredicate); + this.visiblePredicate = visiblePredicate; + } + + @Override + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, + boolean leaf, int row, boolean hasFocus) { + if (row == -1) { + label.setText(""); + return label; + } + + JComponent result = null; + + Icon icon = null; + label.setText(value.toString()); + if (value instanceof MediaType) { + icon = IconManager.getFileIcon(value.toString().split("/")[0], ""); + } + if (value instanceof Category) { + icon = IconManager.getCategoryIcon(((Category) value).getName().toLowerCase()); + label.setText(((Category) value).getName()); + } + + TreePath tp = tree.getPathForRow(row); + + label.setIcon(icon); + + if (visiblePredicate == null || visiblePredicate.test(value)) { + checkbox.setSelected(checkedPredicate.test(value)); + checkbox.setText(value.toString()); + label.setText(""); + result = ckPanel; + } else { + result = label; + } + + return result; + } + + public AbstractButton getCheckbox() { + return checkbox; + } +} diff --git a/iped-app/src/main/java/iped/app/ui/controls/DisabledPanel.java b/iped-app/src/main/java/iped/app/ui/controls/DisabledPanel.java new file mode 100644 index 0000000000..5c8263ecee --- /dev/null +++ b/iped-app/src/main/java/iped/app/ui/controls/DisabledPanel.java @@ -0,0 +1,405 @@ +package iped.app.ui.controls; + +import java.awt.AWTEvent; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.DefaultFocusTraversalPolicy; +import java.awt.EventQueue; +import java.awt.Graphics; +import java.awt.Toolkit; +import java.awt.Window; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseMotionAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.swing.InputMap; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.KeyStroke; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +/* + * The DisablePanel will simulate the usage of a "Glass Pane" except that the + * glass pane effect is only for the container and not the entire frame. + * By default the glass pane is invisible. When the DisablePanel is disabled + * then the glass pane is made visible. In addition: + * + * a) All MouseEvents will now be intercepted by the glass pane. + * b) The panel is removed from the normal focus traveral policy to prevent + * any component on the panel from receiving focus. + * c) Key Bindings for any component on the panel will be intercepted. + * + * Therefore, the panel and components will behave as though they are disabled + * even though the state of each component has not been changed. + * + * The background color of the glass pane should use a color with an + * alpha value to create the disabled look. + * + * The other approach to disabling components on a Container is to recurse + * through all the components and set each individual component disabled. + * This class supports two static methods to support this functionality: + * + * a) disable( Container ) - to disable all Components on the Container + * b) enable ( Container ) - to enable all Components disabled by the + * disable() method. That is any component that was disabled prior to using + * the disable() method method will remain disabled. + */ +public class DisabledPanel extends JPanel { + private static DisabledEventQueue queue = new DisabledEventQueue(); + + private static Map> containers = new HashMap>(); + + private JComponent glassPane; + + /** + * Create a DisablePanel for the specified Container. The disabled color will be + * the following color from the UIManager with an alpha value: + * UIManager.getColor("inactiveCaptionBorder"); + * + * @param container + * a Container to be added to this DisabledPanel + */ + public DisabledPanel(Component component) { + this(component, null); + } + + /** + * Create a DisablePanel for the specified Container using the specified + * disabled color. + * + * @param disabledColor + * the background color of the GlassPane + * @param component + * a Container to be added to this DisabledPanel + */ + public DisabledPanel(Component component, Color disabledColor) { + setLayout(new OverlapLayout()); + add(component); + + glassPane = new GlassPane(); + add(glassPane); + + if (disabledColor != null) + glassPane.setBackground(disabledColor); + + setFocusTraversalPolicy(new DefaultFocusTraversalPolicy()); + } + + /** + * The background color of the glass pane. + * + * @return the background color of the glass pane + */ + public Color getDisabledColor() { + return glassPane.getBackground(); + } + + /** + * Set the background color of the glass pane. This color should contain an + * alpha value to give the glass pane a transparent effect. + * + * @param disabledColor + * the background color of the glass pane + */ + public void setDisabledColor(Color disabledColor) { + glassPane.setBackground(disabledColor); + } + + /** + * The glass pane of this DisablePanel. It can be customized by adding + * components to it. + * + * @return the glass pane + */ + public JComponent getGlassPane() { + return glassPane; + } + + /** + * Use a custom glass pane. You are responsible for adding the appropriate mouse + * listeners to intercept mouse events. + * + * @param glassPane + * a JComponent to be used as a glass pane + */ + public void setGlassPane(JComponent glassPane) { + this.glassPane = glassPane; + } + + /** + * Change the enabled state of the panel. + */ + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + + if (enabled) { + glassPane.setVisible(false); + setFocusCycleRoot(false); + queue.removePanel(this); + } else { + glassPane.setVisible(true); + setFocusCycleRoot(true); // remove from focus cycle + queue.addPanel(this); + } + } + + /** + * Because we use layered panels this should be disabled. + */ + @Override + public boolean isOptimizedDrawingEnabled() { + return false; + } + + /** + * Convenience static method to disable all components of a given Container, + * including nested Containers. + * + * @param container + * the Container containing Components to be disabled + */ + public static void disable(Container container) { + List components = SwingUtils.getDescendantsOfType(JComponent.class, container, true); + List enabledComponents = new ArrayList(); + containers.put(container, enabledComponents); + + for (JComponent component : components) { + if (component.isEnabled()) { + enabledComponents.add(component); + component.setEnabled(false); + } + } + } + + /** + * Convenience static method to enable Components disabled by using the + * disable() method. Only Components disable by the disable() method will be + * enabled. + * + * @param container + * a Container that has been previously disabled. + */ + public static void enable(Container container) { + List enabledComponents = containers.get(container); + + if (enabledComponents != null) { + for (JComponent component : enabledComponents) { + component.setEnabled(true); + } + + containers.remove(container); + } + } + + /** + * A simple "glass pane" that has two functions: + * + * a) to paint over top of the Container added to the DisablePanel b) to + * intercept mouse events when visible + */ + class GlassPane extends JComponent { + public GlassPane() { + setOpaque(false); + setVisible(false); + Color base = UIManager.getColor("inactiveCaptionBorder"); + base = (base == null) ? Color.LIGHT_GRAY : base; + Color background = new Color(base.getRed(), base.getGreen(), base.getBlue(), 128); + setBackground(background); + + // Disable Mouse events for the panel + + addMouseListener(new MouseAdapter() { + }); + addMouseMotionListener(new MouseMotionAdapter() { + }); + } + + /* + * The component is transparent but we want to paint the background to give it + * the disabled look. + */ + @Override + protected void paintComponent(Graphics g) { + g.setColor(getBackground()); + g.fillRect(0, 0, getSize().width, getSize().height); + } + } + + /** + * A custom EventQueue to intercept Key Bindings that are used by any component + * on a DisabledPanel. When a DisabledPanel is disabled it is registered with + * the DisabledEventQueue. This class will check if any components on the + * DisablePanel use KeyBindings. If not then nothing changes. However, if some + * do, then the DisableEventQueue installs itself as the current EquentQueue. + * The dispatchEvent() method is overriden to check each KeyEvent. If the + * KeyEvent is for a Component on a DisablePanel then the event is ignored, + * otherwise it is dispatched for normal processing. + */ + static class DisabledEventQueue extends EventQueue implements WindowListener { + private Map> panels = new HashMap>(); + + /** + * Check if any component on the DisabledPanel is using Key Bindings. If so, + * then track the bindings and use a custom EventQueue to intercept the + * KeyStroke before it is passed to the component. + */ + public void addPanel(DisabledPanel panel) { + // Get all the KeyStrokes used by all the components on the panel + + Set keyStrokes = getKeyStrokes(panel); + + if (keyStrokes.size() == 0) + return; + + panels.put(panel, keyStrokes); + + // More than one panel can be disabled but we only need to install + // the custom EventQueue when the first panel is disabled. + + EventQueue current = Toolkit.getDefaultToolkit().getSystemEventQueue(); + + if (current != this) + current.push(queue); + + // We need to track when a Window is closed so we can remove + // the references for all the DisabledPanels on that window. + + Window window = SwingUtilities.windowForComponent(panel); + window.removeWindowListener(this); + window.addWindowListener(this); + } + + /** + * Check each component to see if its using Key Bindings + */ + private Set getKeyStrokes(DisabledPanel panel) { + Set keyStrokes = new HashSet(); + + // Only JComponents use Key Bindings + + Container container = ((Container) panel.getComponent(1)); + List components = SwingUtils.getDescendantsOfType(JComponent.class, container); + + // We only care about the WHEN_IN_FOCUSED_WINDOW bindings + + for (JComponent component : components) { + InputMap im = component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); + + if (im != null && im.allKeys() != null) { + for (KeyStroke keyStroke : im.allKeys()) + keyStrokes.add(keyStroke); + } + } + + return keyStrokes; + } + + /** + * The panel is no longer disabled so we no longer need to intercept its + * KeyStrokes. Restore the default EventQueue when all panels using Key Bindings + * have been enabled. + */ + public void removePanel(DisabledPanel panel) { + if (panels.remove(panel) != null && panels.size() == 0) + pop(); + } + + /** + * Intercept KeyEvents bound to a component on a DisabledPanel. + */ + @Override + protected void dispatchEvent(AWTEvent event) { + // Potentially intercept KeyEvents + + if (event.getID() == KeyEvent.KEY_TYPED || event.getID() == KeyEvent.KEY_PRESSED + || event.getID() == KeyEvent.KEY_RELEASED) { + KeyEvent keyEvent = (KeyEvent) event; + KeyStroke keyStroke = KeyStroke.getKeyStrokeForEvent(keyEvent); + + // When using Key Bindings, the source of the KeyEvent will be + // the Window. Check each panel belonging to the source Window. + + for (DisabledPanel panel : panels.keySet()) { + Window panelWindow = SwingUtilities.windowForComponent(panel); + + // A binding was found so just return without dispatching it. + + if (panelWindow == keyEvent.getComponent() && searchForKeyBinding(panel, keyStroke)) + return; + } + } + + // Dispatch normally + + super.dispatchEvent(event); + } + + /** + * Check if the KeyStroke is for a Component on the DisablePanel + */ + private boolean searchForKeyBinding(DisabledPanel panel, KeyStroke keyStroke) { + Set keyStrokes = panels.get(panel); + + return keyStrokes.contains(keyStroke); + } + + // Implement WindowListener interface + + /** + * When a Window containing a DisablePanel that has been disabled is closed, + * remove the DisablePanel from the DisabledEventQueue. This may result in the + * DisabledEventQueue deregistering itself as the current EventQueue. + */ + public void windowClosed(WindowEvent e) { + List panelsToRemove = new ArrayList(); + Window window = e.getWindow(); + + // Create a List of DisabledPanels to remove + + for (DisabledPanel panel : panels.keySet()) { + Window panelWindow = SwingUtilities.windowForComponent(panel); + + if (panelWindow == window) { + panelsToRemove.add(panel); + } + } + + // Remove panels here to prevent ConcurrentModificationException + + for (DisabledPanel panel : panelsToRemove) { + removePanel(panel); + } + + window.removeWindowListener(this); + } + + public void windowActivated(WindowEvent e) { + } + + public void windowClosing(WindowEvent e) { + } + + public void windowDeactivated(WindowEvent e) { + } + + public void windowDeiconified(WindowEvent e) { + } + + public void windowIconified(WindowEvent e) { + } + + public void windowOpened(WindowEvent e) { + } + } +} \ No newline at end of file diff --git a/iped-app/src/main/java/iped/app/ui/controls/IPEDConfigSearchList.java b/iped-app/src/main/java/iped/app/ui/controls/IPEDConfigSearchList.java new file mode 100644 index 0000000000..c27a9c711a --- /dev/null +++ b/iped-app/src/main/java/iped/app/ui/controls/IPEDConfigSearchList.java @@ -0,0 +1,208 @@ +package iped.app.ui.controls; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.dnd.DropTarget; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.beans.VetoableChangeListener; +import java.util.List; +import java.util.function.Predicate; + +import javax.swing.DropMode; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.ListSelectionModel; +import javax.swing.ScrollPaneConstants; +import javax.swing.TransferHandler; +import javax.swing.event.ListSelectionListener; + +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rtextarea.RTextScrollPane; + +public class IPEDConfigSearchList extends JPanel { + protected RSyntaxTextArea txFilter; + protected Predicate availablePredicate; + protected List availableItems; + protected JScrollPane listScrollPanel; + protected JList list; + protected Predicate checkTypedContent; + protected int paintRef; + protected int paintSize; + + protected IPEDConfigSearchList() { + this(null); + } + + protected IPEDConfigSearchList(Predicate availablePredicate) { + super(new BorderLayout()); + this.availablePredicate=availablePredicate; + checkTypedContent = new Predicate() { + @Override + public boolean test(E t) { + if(!txFilter.getText().trim().equals("")) { + return !t.toString().contains(txFilter.getText()); + }else { + return false; + } + + } + }; + } + + public void createGUI(IPEDFilterableListModel m) { + list = new JList(m); + + m.setFilter(checkTypedContent); + + txFilter = new RSyntaxTextArea(1, 20); + txFilter.setHighlightCurrentLine(false); + txFilter.addKeyListener(new KeyListener() { + @Override + public void keyTyped(KeyEvent e) { + list.clearSelection(); + list.updateUI(); + } + + @Override + public void keyReleased(KeyEvent e) { + } + + @Override + public void keyPressed(KeyEvent e) { + } + }); + + RTextScrollPane tsFilter = new RTextScrollPane(txFilter); + tsFilter.setBackground(this.getBackground()); + tsFilter.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); + tsFilter.setLineNumbersEnabled(false); + this.add(tsFilter, BorderLayout.NORTH); + listScrollPanel = new JScrollPane(); + listScrollPanel.setBackground(this.getBackground()); + listScrollPanel.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + listScrollPanel.setViewportView(list); + listScrollPanel.setAutoscrolls(true); + list.setDropMode(DropMode.ON); + this.add(listScrollPanel, BorderLayout.CENTER); + } + + @Override + public void setTransferHandler(TransferHandler newHandler) { + list.setTransferHandler(newHandler); + } + + public Color getSelectionForeground() { + return list.getSelectionForeground(); + } + + public void setSelectionForeground(Color selectionForeground) { + list.setSelectionForeground(selectionForeground); + } + + public Color getSelectionBackground() { + return list.getSelectionBackground(); + } + + public void setSelectionBackground(Color selectionBackground) { + list.setSelectionBackground(selectionBackground); + } + + public int getVisibleRowCount() { + return list.getVisibleRowCount(); + } + + public void setDropTarget(DropTarget dt) { + list.setDropTarget(dt); + } + + public void setDragEnabled(boolean b) { + list.setDragEnabled(b); + } + + public final void setDropMode(DropMode dropMode) { + list.setDropMode(dropMode); + } + + public ListSelectionModel getSelectionModel() { + return list.getSelectionModel(); + } + + public ListSelectionListener[] getListSelectionListeners() { + return list.getListSelectionListeners(); + } + + public void setSelectionMode(int selectionMode) { + list.setSelectionMode(selectionMode); + } + + public int getSelectionMode() { + return list.getSelectionMode(); + } + + public void clearSelection() { + list.clearSelection(); + } + + public int[] getSelectedIndices() { + return list.getSelectedIndices(); + } + + public void setSelectedIndex(int index) { + list.setSelectedIndex(index); + } + + public void setSelectedIndices(int[] indices) { + list.setSelectedIndices(indices); + } + + public Object[] getSelectedValues() { + return list.getSelectedValues(); + } + + public List getSelectedValuesList() { + return list.getSelectedValuesList(); + } + + public int getSelectedIndex() { + return list.getSelectedIndex(); + } + + public E getSelectedValue() { + return list.getSelectedValue(); + } + + public void setSelectedValue(Object anObject, boolean shouldScroll) { + list.setSelectedValue(anObject, shouldScroll); + } + + public void addVetoableChangeListener(VetoableChangeListener listener) { + list.addVetoableChangeListener(listener); + } + + public JList getListComponent() { + return list; + } + + @Override + public void paintImmediately(int x, int y, int w, int h) { + paintRef++; + if (paintRef >= 1000000) { + paintRef = 1; + } + paintSize = list.getModel().getSize(); + super.paintImmediately(x, y, w, h); + } + + @Override + protected void paintChildren(Graphics g) { + paintRef++; + if (paintRef >= 1000000) { + paintRef = 1; + } + paintSize = list.getModel().getSize(); + super.paintChildren(g); + } +} diff --git a/iped-app/src/main/java/iped/app/ui/controls/IPEDFilterableListModel.java b/iped-app/src/main/java/iped/app/ui/controls/IPEDFilterableListModel.java new file mode 100644 index 0000000000..83b13e2707 --- /dev/null +++ b/iped-app/src/main/java/iped/app/ui/controls/IPEDFilterableListModel.java @@ -0,0 +1,75 @@ +package iped.app.ui.controls; + +import java.util.Iterator; +import java.util.List; +import java.util.function.Predicate; + +import javax.swing.AbstractListModel; +import javax.swing.event.ListDataListener; + +public class IPEDFilterableListModel extends AbstractListModel { + Predicate toHide; + List list; + private int lastIndex=Integer.MAX_VALUE; + private Iterator iterator; + private E e; + + public IPEDFilterableListModel(List list) { + this.list = list; + } + + public IPEDFilterableListModel(List list, Predicate toHide) { + this(list); + this.toHide = toHide; + } + + @Override + public int getSize() { + int curIndex=0; + if(list!=null) { + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + E e = (E) iterator.next(); + if(toHide==null || !toHide.test(e)) { + curIndex++; + } + } + } + return curIndex; + } + @Override + public E getElementAt(int index) { + if(lastIndex>index) { + iterator = list.iterator(); + lastIndex=-1; + } + if(lastIndex==index) { + return e; + } + for (; iterator.hasNext();) { + e = (E) iterator.next(); + if(toHide==null || !toHide.test(e)) { + lastIndex++; + if(lastIndex==index) { + return e; + } + } + } + return null; + } + @Override + public void addListDataListener(ListDataListener l) { + } + + @Override + public void removeListDataListener(ListDataListener l) { + } + + public Object getViewToModelIndex(int i) { + // TODO Auto-generated method stub + return null; + } + + public void setFilter(Predicate filter) { + this.toHide = filter; + } +} diff --git a/iped-app/src/main/java/iped/app/ui/controls/OverlapLayout.java b/iped-app/src/main/java/iped/app/ui/controls/OverlapLayout.java new file mode 100644 index 0000000000..5fbd9def67 --- /dev/null +++ b/iped-app/src/main/java/iped/app/ui/controls/OverlapLayout.java @@ -0,0 +1,472 @@ +package iped.app.ui.controls; + +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Insets; +import java.awt.LayoutManager2; +import java.awt.Point; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * The OverlapLayout class is a layout manager that lays out a + * container's components in an overlapping fashion. A component can be painted + * "above" or "below" the previous component in the container. + * + * Like the GridLayout, each component is sized to the largest width and height + * of any component in the container. The amount of overlap is controlled by + * specifying the overlap postion of each component. You can simulate, + * left-to-right, right-to-left, top-to-bottom, bottom-to-top and diagonal + * layouts. As well you can "stack" components completely on top of one another. + * In this case the components are sized to the space available in the + * container. + * + * A main usage for this layout might be in the creation of "card games". A few + * features have been added that might be handy in these cases: + * + * a) a "popup" feature - when a component is selected in can "popup" from its + * regular location so it visibly stands out. To accomplish this some extra + * space must be reserved in the container for the popup. This is done by using + * the setPopupInsets method which allow you to control the popup direction. In + * addition you can add/remove a simple constraint to the component. POP_UP will + * popup the component. POP_DOWN or null will paint the component in its regular + * location. b) when a component is made "invisible" you can reserve its + * location in the container so all the other components don't shift. + * + * Note: this layout is achieved by changing the ZOrder of components in the + * container. It will not work for all components as some compnents will always + * paint themselves on the top of others. This seems to happen with components + * like JButton as rollover effects are painted when a mouse moves over the + * components. + */ +public class OverlapLayout implements LayoutManager2, java.io.Serializable { + public static Boolean POP_UP = Boolean.TRUE; + public static Boolean POP_DOWN = Boolean.FALSE; + + private static final int PREFERRED = 0; + private static final int MINIMUM = 1; + + // Indicates how a component is painted + private boolean overlapAbove; + + private Point overlapPosition; + + // Reserve space for invisible components in the Container + private boolean includeInvisible = true; + + // Reserve extra space so a component can "popup" + private Insets popupInsets = new Insets(0, 0, 0, 0); + + // Track original order in which the components where added + private List components = new ArrayList(); + + // Track a constraint added to a component + private HashMap constraints = new HashMap(); + + /** + * Convenience constructor to provide for "stacking" of components. Each + * component will be stacked above the previous component and sized to fill the + * space of the parent container. + */ + public OverlapLayout() { + this(new Point(0, 0)); + } + + /** + * Convenience constructor. Each component will overlap above the previous + * component. + * + * @param overlapPosition + * a Point defining the relative amount of overlap + */ + public OverlapLayout(Point overlapPosition) { + this(overlapPosition, true); + } + + /** + * Create an overlapping layout. + * + * @param overlapPosition + * a Point defining the relative amount of overlap + * @param overlayAbove + * when true components are painted above the previous component, + * otherwise they are painted below. + */ + public OverlapLayout(Point overlapPosition, boolean overlapAbove) { + setOverlapPosition(overlapPosition); + this.overlapAbove = overlapAbove; + } + + /** + * When components are overlapped above the ZOrder of each component is changed + * resulting in the components position in the container being changed. For + * example when you add a component to the end of the container it will be moved + * to the beginning. If you then try to access the component using + * Component.componentAt(), you will get the first component, not the last. + * + * This method will convert the index to you access the proper component. + * + * @param index + * the index to convert + */ + public int convertIndex(int index) { + if (overlapAbove) + return components.size() - index - 1; + else + return index; + } + + /** + * Get the include invisible property + * + * @returns the include invisible property + */ + public boolean isIncludeInvisible() { + return includeInvisible; + } + + /** + * Controls whether spaces should reserved for invisible components in the + * container + * + * @param includeInvisible + * when true, space is reserved otherwise the component is not + * included in the layout sizing + */ + public void setIncludeInvisible(boolean includeInvisible) { + this.includeInvisible = includeInvisible; + } + + /** + * Get the overlapping position of each component + * + * @returns the Point representing the overlapped position + */ + public Point getOverlapPosition() { + return overlapPosition; + } + + /** + * Specify the position where the overlapped component should be painted. + * + * @param overlapPosition + * the position where the next component is painted + */ + public void setOverlapPosition(Point overlapPosition) { + this.overlapPosition = overlapPosition; + } + + /** + * Get the popup insets + * + * @returns the popup insets + */ + public Insets getPopupInsets() { + return popupInsets; + } + + /** + * Define extra space to be reserved by the container. This will allow + * components to be "popped up" if required. Generally space would only be + * reserved on one side of the container. + * + * @param popupInsets + * Insets defining extra space for a particular side of the + * container. + */ + public void setPopupInsets(Insets popupInsets) { + this.popupInsets = popupInsets; + } + + /** + * Gets the constraints for the specified component. + * + * @param component + * the component to be queried + * @return the constraint for the specified component, or null if component is + * null or is not present in this layout + */ + public Boolean getConstraints(Component component) { + return (Boolean) constraints.get(component); + } + + /** + * Adds the specified component with the specified name to the layout. + * + * @param name + * the name of the component + * @param comp + * the component to be added + */ + public void addLayoutComponent(String name, Component comp) { + } + + /* + * Keep track of any specified constraint for the component. + */ + public void addLayoutComponent(Component component, Object constraint) { + // Support simple Boolean constraint for painting a Component in + // its "popped up" position + + if (constraint == null) { + constraints.remove(component); + } else if (constraint instanceof Boolean) { + constraints.put(component, (Boolean) constraint); + } else { + String message = "Constraint parameter must be of type Boolean"; + throw new IllegalArgumentException(message); + } + + // Keep a separate List of components in the order in which they where + // added to the Container. This makes layout easier. First we need + // to find the position the component was added at. We can't depend + // on the component order in the parent Container as changing the + // Z-Order also changes the order in the Container + + if (!components.contains(component)) { + Container parent = component.getParent(); + int size = parent.getComponentCount(); + + for (int i = 0; i < size; i++) { + Component c = parent.getComponent(i); + + if (c == component) { + components.add(i, component); + + // Need to change Z-Order so added components are painted + // above the previously added component. + + if (overlapAbove) { + parent.setComponentZOrder(component, size - i - 1); + } + + break; + } + } + } + } + + /** + * Removes the specified component from the layout. + * + * @param comp + * the component to be removed + */ + public void removeLayoutComponent(Component component) { + components.remove(component); + constraints.remove(component); + } + + /** + * Determine the minimum size on the Container + * + * @param target + * the container in which to do the layout + * @return the minimum dimensions needed to lay out the subcomponents of the + * specified container + */ + public Dimension minimumLayoutSize(Container parent) { + synchronized (parent.getTreeLock()) { + return getLayoutSize(parent, MINIMUM); + } + } + + /** + * Determine the preferred size on the Container + * + * @param parent + * the container in which to do the layout + * @return the preferred dimensions to lay out the subcomponents of the + * specified container + */ + public Dimension preferredLayoutSize(Container parent) { + synchronized (parent.getTreeLock()) { + return getLayoutSize(parent, PREFERRED); + } + } + + /* + * The calculation for minimum/preferred size it the same. The only difference + * is the need to use the minimum or preferred size of the component in the + * calculation. + * + * @param parent the container in which to do the layout + * + * @param type either MINIMUM or PREFERRED + */ + private Dimension getLayoutSize(Container parent, int type) { + int visibleComponents = 0; + int width = 0; + int height = 0; + + // All components will be resized to the maximum dimension + + for (Component component : components) { + if (component.isVisible() || includeInvisible) { + Dimension size = getDimension(component, type); + width = Math.max(size.width, width); + height = Math.max(size.height, height); + visibleComponents++; + } + } + + if (visibleComponents == 0) + return new Dimension(0, 0); + + // Adjust size for each overlapping component + + visibleComponents--; + width += visibleComponents * Math.abs(overlapPosition.x); + height += visibleComponents * Math.abs(overlapPosition.y); + + // Adjust for parent Container and popup insets + + Insets parentInsets = parent.getInsets(); + width += parentInsets.left + parentInsets.right; + height += parentInsets.top + parentInsets.bottom; + + width += popupInsets.left + popupInsets.right; + height += popupInsets.top + popupInsets.bottom; + + return new Dimension(width, height); + } + + private Dimension getDimension(Component component, int type) { + switch (type) { + case PREFERRED: + return component.getPreferredSize(); + case MINIMUM: + return component.getMinimumSize(); + default: + return new Dimension(0, 0); + } + } + + /** + * Lays out the specified container using this layout. + *

+ * + * @param target + * the container in which to do the layout + */ + public void layoutContainer(Container parent) { + synchronized (parent.getTreeLock()) { + int size = components.size(); + + if (size == 0) + return; + + // Determine the maximum size of the components + + Dimension maximumSize = new Dimension(); + + for (Component component : components) { + if (component.isVisible() || includeInvisible) { + Dimension preferred = component.getPreferredSize(); + maximumSize.width = Math.max(preferred.width, maximumSize.width); + maximumSize.height = Math.max(preferred.height, maximumSize.height); + } + } + + // Determine location of first component + + Point location = new Point(0, 0); + Insets parentInsets = parent.getInsets(); + + // Layout right-to-left, else left-to-right + + if (overlapPosition.x < 0) + location.x = parent.getWidth() - maximumSize.width - parentInsets.right - popupInsets.right; + else + location.x = parentInsets.left + popupInsets.left; + + // Layout bottom-to-top, else top-to-bottom + + if (overlapPosition.y < 0) + location.y = parent.getHeight() - maximumSize.height - parentInsets.bottom - popupInsets.bottom; + else + location.y = parentInsets.top + popupInsets.top; + + // Set the size and location for each component + + for (int i = 0; i < size; i++) { + Component component = components.get(i); + + if (component.isVisible() || includeInvisible) { + // When components are "stacked" resize each component to fill + // the size of the parent container + + if (overlapPosition.x == 0 && overlapPosition.y == 0) { + int width = parent.getWidth() - parentInsets.left - parentInsets.right; + int height = parent.getHeight() - parentInsets.top - parentInsets.bottom; + component.setSize(width, height); + } else // resize each component to be the same size + { + component.setSize(maximumSize); + } + + // Set location of the component + + int x = location.x; + int y = location.y; + + // Adjust location when component is "popped up" + + Boolean constraint = constraints.get(component); + + if (constraint != null && constraint == Boolean.TRUE) { + x += popupInsets.right - popupInsets.left; + y += popupInsets.bottom - popupInsets.top; + } + + component.setLocation(x, y); + + // Calculate location of next component using the overlap offsets + + location.x += overlapPosition.x; + location.y += overlapPosition.y; + } + } + } + } + + /** + * There is no maximum. + */ + public Dimension maximumLayoutSize(Container target) { + return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); + } + + /** + * Returns the alignment along the x axis. Use center alignment. + */ + public float getLayoutAlignmentX(Container parent) { + return 0.5f; + } + + /** + * Returns the alignment along the y axis. Use center alignment. + */ + public float getLayoutAlignmentY(Container parent) { + return 0.5f; + } + + /** + * Invalidates the layout, indicating that if the layout manager has cached + * information it should be discarded. + */ + public void invalidateLayout(Container target) { + // remove constraints here? + } + + /** + * Returns the string representation of this column layout's values. + * + * @return a string representation of this grid layout + */ + public String toString() { + return getClass().getName() + "[overlapAbove=" + overlapAbove + ",overlapPosition=" + overlapPosition + "]"; + } +} \ No newline at end of file diff --git a/iped-app/src/main/java/iped/app/ui/controls/SwingUtils.java b/iped-app/src/main/java/iped/app/ui/controls/SwingUtils.java new file mode 100644 index 0000000000..da9cc7a244 --- /dev/null +++ b/iped-app/src/main/java/iped/app/ui/controls/SwingUtils.java @@ -0,0 +1,458 @@ +package iped.app.ui.controls; +/* + * @(#)SwingUtils.java 1.02 11/15/08 + * + */ + +//package darrylbu.util; + +import java.awt.Component; +import java.awt.Container; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.swing.JComponent; +import javax.swing.UIDefaults; +import javax.swing.UIManager; + +/** + * A collection of utility methods for Swing. + * + * @author Darryl Burke + */ +public final class SwingUtils { + + private SwingUtils() { + throw new Error("SwingUtils is just a container for static methods"); + } + + /** + * Convenience method for searching below container in the + * component hierarchy and return nested components that are instances of class + * clazz it finds. Returns an empty list if no such components + * exist in the container. + *

+ * Invoking this method with a class parameter of JComponent.class will return + * all nested components. + *

+ * This method invokes getDescendantsOfType(clazz, container, true) + * + * @param clazz + * the class of components whose instances are to be found. + * @param container + * the container at which to begin the search + * @return the List of components + */ + public static List getDescendantsOfType(Class clazz, Container container) { + return getDescendantsOfType(clazz, container, true); + } + + /** + * Convenience method for searching below container in the + * component hierarchy and return nested components that are instances of class + * clazz it finds. Returns an empty list if no such components + * exist in the container. + *

+ * Invoking this method with a class parameter of JComponent.class will return + * all nested components. + * + * @param clazz + * the class of components whose instances are to be found. + * @param container + * the container at which to begin the search + * @param nested + * true to list components nested within another listed component, + * false otherwise + * @return the List of components + */ + public static List getDescendantsOfType(Class clazz, Container container, + boolean nested) { + List tList = new ArrayList(); + for (Component component : container.getComponents()) { + if (clazz.isAssignableFrom(component.getClass())) { + tList.add(clazz.cast(component)); + } + if (nested || !clazz.isAssignableFrom(component.getClass())) { + tList.addAll(SwingUtils.getDescendantsOfType(clazz, (Container) component, nested)); + } + } + return tList; + } + + /** + * Convenience method that searches below container in the + * component hierarchy and returns the first found component that is an instance + * of class clazz having the bound property value. Returns + * {@code null} if such component cannot be found. + *

+ * This method invokes getDescendantOfType(clazz, container, property, value, + * true) + * + * @param clazz + * the class of component whose instance is to be found. + * @param container + * the container at which to begin the search + * @param property + * the className of the bound property, exactly as expressed in the + * accessor e.g. "Text" for getText(), "Value" for getValue(). + * @param value + * the value of the bound property + * @return the component, or null if no such component exists in the container + * @throws java.lang.IllegalArgumentException + * if the bound property does not exist for the class or cannot be + * accessed + */ + public static T getDescendantOfType(Class clazz, Container container, String property, + Object value) throws IllegalArgumentException { + return getDescendantOfType(clazz, container, property, value, true); + } + + /** + * Convenience method that searches below container in the + * component hierarchy and returns the first found component that is an instance + * of class clazz and has the bound property value. Returns + * {@code null} if such component cannot be found. + * + * @param clazz + * the class of component whose instance to be found. + * @param container + * the container at which to begin the search + * @param property + * the className of the bound property, exactly as expressed in the + * accessor e.g. "Text" for getText(), "Value" for getValue(). + * @param value + * the value of the bound property + * @param nested + * true to list components nested within another component which is + * also an instance of clazz, false otherwise + * @return the component, or null if no such component exists in the container + * @throws java.lang.IllegalArgumentException + * if the bound property does not exist for the class or cannot be + * accessed + */ + public static T getDescendantOfType(Class clazz, Container container, String property, + Object value, boolean nested) throws IllegalArgumentException { + List list = getDescendantsOfType(clazz, container, nested); + return getComponentFromList(clazz, list, property, value); + } + + /** + * Convenience method for searching below container in the + * component hierarchy and return nested components of class clazz + * it finds. Returns an empty list if no such components exist in the container. + *

+ * This method invokes getDescendantsOfClass(clazz, container, true) + * + * @param clazz + * the class of components to be found. + * @param container + * the container at which to begin the search + * @return the List of components + */ + public static List getDescendantsOfClass(Class clazz, Container container) { + return getDescendantsOfClass(clazz, container, true); + } + + /** + * Convenience method for searching below container in the + * component hierarchy and return nested components of class clazz + * it finds. Returns an empty list if no such components exist in the container. + * + * @param clazz + * the class of components to be found. + * @param container + * the container at which to begin the search + * @param nested + * true to list components nested within another listed component, + * false otherwise + * @return the List of components + */ + public static List getDescendantsOfClass(Class clazz, Container container, + boolean nested) { + List tList = new ArrayList(); + for (Component component : container.getComponents()) { + if (clazz.equals(component.getClass())) { + tList.add(clazz.cast(component)); + } + if (nested || !clazz.equals(component.getClass())) { + tList.addAll(SwingUtils.getDescendantsOfClass(clazz, (Container) component, nested)); + } + } + return tList; + } + + /** + * Convenience method that searches below container in the + * component hierarchy in a depth first manner and returns the first found + * component of class clazz having the bound property value. + *

+ * Returns {@code null} if such component cannot be found. + *

+ * This method invokes getDescendantOfClass(clazz, container, property, value, + * true) + * + * @param clazz + * the class of component to be found. + * @param container + * the container at which to begin the search + * @param property + * the className of the bound property, exactly as expressed in the + * accessor e.g. "Text" for getText(), "Value" for getValue(). This + * parameter is case sensitive. + * @param value + * the value of the bound property + * @return the component, or null if no such component exists in the container's + * hierarchy. + * @throws java.lang.IllegalArgumentException + * if the bound property does not exist for the class or cannot be + * accessed + */ + public static T getDescendantOfClass(Class clazz, Container container, String property, + Object value) throws IllegalArgumentException { + return getDescendantOfClass(clazz, container, property, value, true); + } + + /** + * Convenience method that searches below container in the + * component hierarchy in a depth first manner and returns the first found + * component of class clazz having the bound property value. + *

+ * Returns {@code null} if such component cannot be found. + * + * @param clazz + * the class of component to be found. + * @param container + * the container at which to begin the search + * @param property + * the className of the bound property, exactly as expressed in the + * accessor e.g. "Text" for getText(), "Value" for getValue(). This + * parameter is case sensitive. + * @param value + * the value of the bound property + * @param nested + * true to include components nested within another listed component, + * false otherwise + * @return the component, or null if no such component exists in the container's + * hierarchy + * @throws java.lang.IllegalArgumentException + * if the bound property does not exist for the class or cannot be + * accessed + */ + public static T getDescendantOfClass(Class clazz, Container container, String property, + Object value, boolean nested) throws IllegalArgumentException { + List list = getDescendantsOfClass(clazz, container, nested); + return getComponentFromList(clazz, list, property, value); + } + + private static T getComponentFromList(Class clazz, List list, String property, + Object value) throws IllegalArgumentException { + T retVal = null; + Method method = null; + try { + method = clazz.getMethod("get" + property); + } catch (NoSuchMethodException ex) { + try { + method = clazz.getMethod("is" + property); + } catch (NoSuchMethodException ex1) { + throw new IllegalArgumentException("Property " + property + " not found in class " + clazz.getName()); + } + } + try { + for (T t : list) { + Object testVal = method.invoke(t); + if (equals(value, testVal)) { + return t; + } + } + } catch (InvocationTargetException ex) { + throw new IllegalArgumentException("Error accessing property " + property + " in class " + clazz.getName()); + } catch (IllegalAccessException ex) { + throw new IllegalArgumentException( + "Property " + property + " cannot be accessed in class " + clazz.getName()); + } catch (SecurityException ex) { + throw new IllegalArgumentException( + "Property " + property + " cannot be accessed in class " + clazz.getName()); + } + return retVal; + } + + /** + * Convenience method for determining whether two objects are either equal or + * both null. + * + * @param obj1 + * the first reference object to compare. + * @param obj2 + * the second reference object to compare. + * @return true if obj1 and obj2 are equal or if both are null, false otherwise + */ + public static boolean equals(Object obj1, Object obj2) { + return obj1 == null ? obj2 == null : obj1.equals(obj2); + } + + /** + * Convenience method for mapping a container in the hierarchy to its contained + * components. The keys are the containers, and the values are lists of + * contained components. + *

+ * Implementation note: The returned value is a HashMap and the values are of + * type ArrayList. This is subject to change, so callers should code against the + * interfaces Map and List. + * + * @param container + * The JComponent to be mapped + * @param nested + * true to drill down to nested containers, false otherwise + * @return the Map of the UI + */ + public static Map> getComponentMap(JComponent container, boolean nested) { + HashMap> retVal = new HashMap>(); + for (JComponent component : getDescendantsOfType(JComponent.class, container, false)) { + if (!retVal.containsKey(container)) { + retVal.put(container, new ArrayList()); + } + retVal.get(container).add(component); + if (nested) { + retVal.putAll(getComponentMap(component, nested)); + } + } + return retVal; + } + + /** + * Convenience method for retrieving a subset of the UIDefaults pertaining to a + * particular class. + * + * @param clazz + * the class of interest + * @return the UIDefaults of the class + */ + public static UIDefaults getUIDefaultsOfClass(Class clazz) { + String name = clazz.getName(); + name = name.substring(name.lastIndexOf(".") + 2); + return getUIDefaultsOfClass(name); + } + + /** + * Convenience method for retrieving a subset of the UIDefaults pertaining to a + * particular class. + * + * @param className + * fully qualified name of the class of interest + * @return the UIDefaults of the class named + */ + public static UIDefaults getUIDefaultsOfClass(String className) { + UIDefaults retVal = new UIDefaults(); + UIDefaults defaults = UIManager.getLookAndFeelDefaults(); + List listKeys = Collections.list(defaults.keys()); + for (Object key : listKeys) { + if (key instanceof String && ((String) key).startsWith(className)) { + String stringKey = (String) key; + String property = stringKey; + if (stringKey.contains(".")) { + property = stringKey.substring(stringKey.indexOf(".") + 1); + } + retVal.put(property, defaults.get(key)); + } + } + return retVal; + } + + /** + * Convenience method for retrieving the UIDefault for a single property of a + * particular class. + * + * @param clazz + * the class of interest + * @param property + * the property to query + * @return the UIDefault property, or null if not found + */ + public static Object getUIDefaultOfClass(Class clazz, String property) { + Object retVal = null; + UIDefaults defaults = getUIDefaultsOfClass(clazz); + List listKeys = Collections.list(defaults.keys()); + for (Object key : listKeys) { + if (key.equals(property)) { + return defaults.get(key); + } + if (key.toString().equalsIgnoreCase(property)) { + retVal = defaults.get(key); + } + } + return retVal; + } + + /** + * Exclude methods that return values that are meaningless to the user + */ + static Set setExclude = new HashSet(); + static { + setExclude.add("getFocusCycleRootAncestor"); + setExclude.add("getAccessibleContext"); + setExclude.add("getColorModel"); + setExclude.add("getGraphics"); + setExclude.add("getGraphicsConfiguration"); + } + + /** + * Convenience method for obtaining most non-null human readable properties of a + * JComponent. Array properties are not included. + *

+ * Implementation note: The returned value is a HashMap. This is subject to + * change, so callers should code against the interface Map. + * + * @param component + * the component whose proerties are to be determined + * @return the class and value of the properties + */ + public static Map getProperties(JComponent component) { + Map retVal = new HashMap(); + Class clazz = component.getClass(); + Method[] methods = clazz.getMethods(); + Object value = null; + for (Method method : methods) { + if (method.getName().matches("^(is|get).*") && method.getParameterTypes().length == 0) { + try { + Class returnType = method.getReturnType(); + if (returnType != void.class && !returnType.getName().startsWith("[") + && !setExclude.contains(method.getName())) { + String key = method.getName(); + value = method.invoke(component); + if (value != null && !(value instanceof Component)) { + retVal.put(key, value); + } + } + // ignore exceptions that arise if the property could not be accessed + } catch (IllegalAccessException ex) { + } catch (IllegalArgumentException ex) { + } catch (InvocationTargetException ex) { + } + } + } + return retVal; + } + + /** + * Convenience method to obtain the Swing class from which this component was + * directly or indirectly derived. + * + * @param component + * The component whose Swing superclass is to be determined + * @return The nearest Swing class in the inheritance tree + */ + public static Class getJClass(T component) { + Class clazz = component.getClass(); + while (!clazz.getName().matches("javax.swing.J[^.]*$")) { + clazz = clazz.getSuperclass(); + } + return clazz; + } +} \ No newline at end of file diff --git a/iped-app/src/main/java/iped/app/ui/controls/textarea/JSONEditorKit.java b/iped-app/src/main/java/iped/app/ui/controls/textarea/JSONEditorKit.java new file mode 100644 index 0000000000..5cff25bdcd --- /dev/null +++ b/iped-app/src/main/java/iped/app/ui/controls/textarea/JSONEditorKit.java @@ -0,0 +1,23 @@ +package iped.app.ui.controls.textarea; + +import javax.swing.text.StyledEditorKit; +import javax.swing.text.ViewFactory; + +public class JSONEditorKit extends StyledEditorKit { + + private ViewFactory jsonViewFactory; + + public JSONEditorKit() { + jsonViewFactory = new JSONViewFactory(); + } + + @Override + public ViewFactory getViewFactory() { + return jsonViewFactory; + } + + @Override + public String getContentType() { + return "text/xml"; + } +} diff --git a/iped-app/src/main/java/iped/app/ui/controls/textarea/JSONView.java b/iped-app/src/main/java/iped/app/ui/controls/textarea/JSONView.java new file mode 100644 index 0000000000..ab17b39462 --- /dev/null +++ b/iped-app/src/main/java/iped/app/ui/controls/textarea/JSONView.java @@ -0,0 +1,30 @@ +package iped.app.ui.controls.textarea; + +import java.awt.Color; +import java.util.HashMap; +import java.util.regex.Pattern; + +import javax.swing.text.Element; + +public class JSONView extends RegexView { + + private static String TAG_PATTERN = "(\"[^\"]*\"\\s*:)"; + private static String TAG_END_PATTERN = "(\"[^\"]*\"\\s*[,\\}\\]])"; + private static String TAG_COMMENT = "()"; + + protected void configPatterns(){ + String TAG_PATTERN = "(\"[^\"]*\"\\s*:)"; + String TAG_END_PATTERN = "(\"[^\"]*\"\\s*[,\\}\\]])"; + String TAG_COMMENT = "()"; + + // NOTE: the order is important! + patternColors = new HashMap(); + patternColors.put(Pattern.compile(TAG_PATTERN), new Color(63, 127, 127)); + patternColors.put(Pattern.compile(TAG_END_PATTERN), new Color(127, 63, 63)); + } + public JSONView(Element elem) { + super(elem); + configPatterns(); + } + +} diff --git a/iped-app/src/main/java/iped/app/ui/controls/textarea/JSONViewFactory.java b/iped-app/src/main/java/iped/app/ui/controls/textarea/JSONViewFactory.java new file mode 100644 index 0000000000..f891a11813 --- /dev/null +++ b/iped-app/src/main/java/iped/app/ui/controls/textarea/JSONViewFactory.java @@ -0,0 +1,14 @@ +package iped.app.ui.controls.textarea; + +import javax.swing.text.Element; +import javax.swing.text.View; +import javax.swing.text.ViewFactory; + +public class JSONViewFactory implements ViewFactory { + + @Override + public View create(Element elem) { + return new JSONView(elem); + } + +} diff --git a/iped-app/src/main/java/iped/app/ui/controls/textarea/RegexTextPane.java b/iped-app/src/main/java/iped/app/ui/controls/textarea/RegexTextPane.java new file mode 100644 index 0000000000..88564d83a7 --- /dev/null +++ b/iped-app/src/main/java/iped/app/ui/controls/textarea/RegexTextPane.java @@ -0,0 +1,12 @@ +package iped.app.ui.controls.textarea; + +import java.awt.Font; + +import javax.swing.JEditorPane; + +public class RegexTextPane extends JEditorPane { + + public RegexTextPane() { + this.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); + } +} diff --git a/iped-app/src/main/java/iped/app/ui/controls/textarea/RegexView.java b/iped-app/src/main/java/iped/app/ui/controls/textarea/RegexView.java new file mode 100644 index 0000000000..43930e5bf3 --- /dev/null +++ b/iped-app/src/main/java/iped/app/ui/controls/textarea/RegexView.java @@ -0,0 +1,92 @@ +package iped.app.ui.controls.textarea; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics; +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.swing.text.BadLocationException; +import javax.swing.text.Document; +import javax.swing.text.Element; +import javax.swing.text.PlainDocument; +import javax.swing.text.PlainView; +import javax.swing.text.Segment; +import javax.swing.text.Utilities; + +public abstract class RegexView extends PlainView { + protected HashMap patternColors; + + public RegexView(Element elem) { + super(elem); + getDocument().putProperty(PlainDocument.tabSizeAttribute, 4); + } + + abstract protected void configPatterns(); + + private TreeMap startMap; + private TreeMap colorMap; + + @Override + protected int drawUnselectedText(Graphics graphics, int x, int y, int p0, + int p1) throws BadLocationException { + Document doc = getDocument(); + String text = doc.getText(p0, p1 - p0); + + Segment segment = getLineBuffer(); + + startMap = new TreeMap(); + colorMap = new TreeMap(); + + if(patternColors!=null) { + // Match all regexes on this snippet, store positions + for (Map.Entry entry : patternColors.entrySet()) { + + Matcher matcher = entry.getKey().matcher(text); + + while (matcher.find()) { + startMap.put(matcher.start(1), matcher.end()); + colorMap.put(matcher.start(1), entry.getValue()); + } + } + } + + // TODO: check the map for overlapping parts + + int i = 0; + + Font originalFont = graphics.getFont(); + Font taggedFont = new Font(graphics.getFont().getName(), Font.ITALIC + Font.BOLD, graphics.getFont().getSize()); + // Colour the parts + for (Map.Entry entry : startMap.entrySet()) { + int start = entry.getKey(); + int end = entry.getValue(); + + graphics.setFont(originalFont); + if (i < start) { + graphics.setColor(Color.black); + doc.getText(p0 + i, start - i, segment); + x = Utilities.drawTabbedText(segment, x, y, graphics, this, i); + } + + graphics.setColor(colorMap.get(start)); + i = end; + doc.getText(p0 + start, i - start, segment); + graphics.setFont(taggedFont); + x = Utilities.drawTabbedText(segment, x, y, graphics, this, start); + } + + // Paint possible remaining text black + if (i < text.length()) { + graphics.setColor(Color.black); + doc.getText(p0 + i, text.length() - i, segment); + x = Utilities.drawTabbedText(segment, x, y, graphics, this, i); + } + + return x; + } + +} diff --git a/iped-app/src/main/java/iped/app/ui/controls/textarea/XMLXSDTokenMaker.java b/iped-app/src/main/java/iped/app/ui/controls/textarea/XMLXSDTokenMaker.java new file mode 100644 index 0000000000..8418e2d8fc --- /dev/null +++ b/iped-app/src/main/java/iped/app/ui/controls/textarea/XMLXSDTokenMaker.java @@ -0,0 +1,151 @@ +package iped.app.ui.controls.textarea; + +import java.awt.Color; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.swing.text.Segment; +import javax.xml.namespace.QName; +import javax.xml.transform.stream.StreamSource; + +import org.apache.ws.commons.schema.XmlSchema; +import org.apache.ws.commons.schema.XmlSchemaChoice; +import org.apache.ws.commons.schema.XmlSchemaChoiceMember; +import org.apache.ws.commons.schema.XmlSchemaCollection; +import org.apache.ws.commons.schema.XmlSchemaComplexType; +import org.apache.ws.commons.schema.XmlSchemaElement; +import org.apache.ws.commons.schema.XmlSchemaParticle; +import org.apache.ws.commons.schema.XmlSchemaSequence; +import org.apache.ws.commons.schema.XmlSchemaSequenceMember; +import org.apache.ws.commons.schema.XmlSchemaType; +import org.fife.ui.rsyntaxtextarea.Token; +import org.fife.ui.rsyntaxtextarea.modes.XMLTokenMaker; + +import iped.engine.task.carver.XMLCarverConfiguration; + +public class XMLXSDTokenMaker extends XMLTokenMaker { + static public int MARKUP_TAG_NAME = 26; + static final public String SYNTAX_STYLE_XMLXSD = "application/xml+xsd"; + public static final int RESERVED_WORD = 6; + URL xsdFile; + private HashMap tagNames; + + public XMLXSDTokenMaker() { + xsdFile = XMLCarverConfiguration.xsdFile; + loadXSDTagName(); + } + + @Override + public Token getTokenList(Segment text, int initialTokenType, int startOffset) { + Token first = super.getTokenList(text, initialTokenType, startOffset); + + Token next = first; + while(next!=null) { + if(next.getType() == XMLXSDTokenMaker.MARKUP_TAG_NAME) { + String tagName = next.getLexeme(); + if(!tagNames.keySet().contains(tagName)) { + next.setType(XMLXSDTokenMaker.RESERVED_WORD); + } + }else { + + } + next=next.getNextToken(); + } + + + return first; + } + + protected void loadXSDTagName(){ + if(xsdFile!=null) { + tagNames = new HashMap(); + try { + XmlSchemaCollection xsc = new XmlSchemaCollection(); + XmlSchema xs = xsc.read(new StreamSource(xsdFile.openStream())); + Map elements = xs.getElements(); + String elementPattern; + String unknownElementPattern; + for (Iterator iterator = elements.entrySet().iterator(); iterator.hasNext();) { + Entry element = (Entry) iterator.next(); + elementPattern = element.getKey().getLocalPart(); + unknownElementPattern = element.getKey().getLocalPart(); + + tagNames.put(elementPattern , new Color(63, 127, 127)); + Map> childElementHierarchy = new HashMap>(); + ArrayList childElements = new ArrayList(); + getChildElementNames(element.getValue(), childElementHierarchy,childElements); + for (Iterator iterator2 = childElements.iterator(); iterator2.hasNext();) { + XmlSchemaElement xmlSchemaElement = (XmlSchemaElement) iterator2.next(); + elementPattern = xmlSchemaElement.getQName().getLocalPart(); + tagNames.put(elementPattern , new Color(63, 127, 127)); + } + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + } + + // Method to check for the child elements and return list + private static void getChildElementNames(XmlSchemaElement element, Map> xsdElements, List elements) { + + // Get the type of the element + XmlSchemaType elementType = element != null ? element.getSchemaType() : null; + + + // Confirm if the element is of Complex type + if (elementType instanceof XmlSchemaComplexType) { + // Get all particles associated with that element Type + XmlSchemaParticle allParticles = ((XmlSchemaComplexType) elementType).getParticle(); + + // Check particle belongs to which type + if ((allParticles instanceof XmlSchemaSequence)) { + // System.out.println("Sequence Schema Type"); + final XmlSchemaSequence xmlSchemaSequence = (XmlSchemaSequence) allParticles; + final List items = xmlSchemaSequence.getItems(); + + items.forEach((item) -> { + XmlSchemaElement itemElements = (XmlSchemaElement) item; + addChild(element.getQName(), itemElements, xsdElements); + elements.add(itemElements); + // Call method recursively to get all subsequent element + getChildElementNames(itemElements, xsdElements, elements); + }); + + } + // Check particle belongs to which type + if ((allParticles instanceof XmlSchemaChoice)) { + // System.out.println("Sequence Schema Type"); + final XmlSchemaChoice xmlSchemaSequence = (XmlSchemaChoice) allParticles; + final List items = xmlSchemaSequence.getItems(); + + items.forEach((item) -> { + XmlSchemaElement itemElements = (XmlSchemaElement) item; + addChild(element.getQName(), itemElements, xsdElements); + elements.add(itemElements); + // Call method recursively to get all subsequent element + getChildElementNames(itemElements, xsdElements, elements); + }); + + } + } + } + + // Add child elements based on its parent + private static void addChild(QName qName, XmlSchemaElement child, Map> xsdElements) { + List values = xsdElements.get(qName); + if (values == null) { + values = new ArrayList(); + } + values.add(child); + xsdElements.put(qName, values); + } +} diff --git a/iped-app/src/main/java/iped/app/ui/controls/textarea/XmlEditorKit.java b/iped-app/src/main/java/iped/app/ui/controls/textarea/XmlEditorKit.java new file mode 100644 index 0000000000..47cbb7b446 --- /dev/null +++ b/iped-app/src/main/java/iped/app/ui/controls/textarea/XmlEditorKit.java @@ -0,0 +1,30 @@ +package iped.app.ui.controls.textarea; + +import java.net.URL; + +import javax.swing.text.StyledEditorKit; +import javax.swing.text.ViewFactory; + +public class XmlEditorKit extends StyledEditorKit { + + private XmlViewFactory xmlViewFactory; + + public XmlEditorKit() { + xmlViewFactory = new XmlViewFactory(); + } + + @Override + public ViewFactory getViewFactory() { + return xmlViewFactory; + } + + @Override + public String getContentType() { + return "text/xml"; + } + + public void setSchema(URL xsdFile) { + xmlViewFactory.setSchema(xsdFile); + + } +} diff --git a/iped-app/src/main/java/iped/app/ui/controls/textarea/XmlView.java b/iped-app/src/main/java/iped/app/ui/controls/textarea/XmlView.java new file mode 100644 index 0000000000..d72a539cb2 --- /dev/null +++ b/iped-app/src/main/java/iped/app/ui/controls/textarea/XmlView.java @@ -0,0 +1,157 @@ +package iped.app.ui.controls.textarea; + +import java.awt.Color; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.regex.Pattern; + +import javax.swing.text.Element; +import javax.xml.namespace.QName; +import javax.xml.transform.stream.StreamSource; + +import org.apache.ws.commons.schema.XmlSchema; +import org.apache.ws.commons.schema.XmlSchemaChoice; +import org.apache.ws.commons.schema.XmlSchemaChoiceMember; +import org.apache.ws.commons.schema.XmlSchemaCollection; +import org.apache.ws.commons.schema.XmlSchemaComplexType; +import org.apache.ws.commons.schema.XmlSchemaElement; +import org.apache.ws.commons.schema.XmlSchemaParticle; +import org.apache.ws.commons.schema.XmlSchemaSequence; +import org.apache.ws.commons.schema.XmlSchemaSequenceMember; +import org.apache.ws.commons.schema.XmlSchemaType; + +public class XmlView extends RegexView { + URL xsdFile = null; + + private static String TAG_PATTERN = "(?"; + private static String OPEN_TAG_PATTERN = ""; + private static String TAG_END_PATTERN = "(/>)"; + private static String TAG_ATTRIBUTE_PATTERN = "\\s(\\w*)\\="; + private static String TAG_ATTRIBUTE_VALUE = "[a-zA-Z-]*\\=(\"[^\"]*\")"; + private static String TAG_COMMENT = "()"; + private static String TAG_CDATA_START = "(\\)"; + + protected void configPatterns(){ + if(xsdFile==null) { + patternColors = new HashMap(); + patternColors.put(Pattern.compile(TAG_CDATA_START), new Color(128, 128, 128)); + patternColors.put(Pattern.compile(TAG_CDATA_END), new Color(128, 128, 128)); + patternColors + .put(Pattern.compile(TAG_PATTERN), new Color(63, 127, 127)); + patternColors.put(Pattern.compile(TAG_ATTRIBUTE_PATTERN), new Color( + 127, 0, 127)); + patternColors.put(Pattern.compile(TAG_END_PATTERN), new Color(63, 127, + 127)); + patternColors.put(Pattern.compile(TAG_ATTRIBUTE_VALUE), new Color(42, + 0, 255)); + patternColors.put(Pattern.compile(TAG_COMMENT), new Color(63, 95, 191)); + }else { + patternColors = new HashMap(); + try { + XmlSchemaCollection xsc = new XmlSchemaCollection(); + XmlSchema xs = xsc.read(new StreamSource(xsdFile.openStream())); + Map elements = xs.getElements(); + String unknownElementPattern = "("+OPEN_TAG_PATTERN + "("; + String elementPattern = "("+OPEN_TAG_PATTERN + "("; + for (Iterator iterator = elements.entrySet().iterator(); iterator.hasNext();) { + Entry element = (Entry) iterator.next(); + elementPattern += "("+element.getKey().getLocalPart()+")|"; + unknownElementPattern += "("+element.getKey().getLocalPart()+")|"; + + Map> childElementHierarchy = new HashMap>(); + ArrayList childElements = new ArrayList(); + getChildElementNames(element.getValue(), childElementHierarchy,childElements); + for (Iterator iterator2 = childElements.iterator(); iterator2.hasNext();) { + XmlSchemaElement xmlSchemaElement = (XmlSchemaElement) iterator2.next(); + elementPattern += "("+xmlSchemaElement.getQName().getLocalPart()+")|"; + unknownElementPattern += "("+xmlSchemaElement.getQName().getLocalPart()+")|"; + } + } + elementPattern += ")"+CLOSE_TAG_PATTERN+")"; + unknownElementPattern += ")"+CLOSE_TAG_PATTERN+")"; + patternColors.put(Pattern.compile(elementPattern), new Color(63, 127, 127)); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + } + + + // Method to check for the child elements and return list + private static void getChildElementNames(XmlSchemaElement element, Map> xsdElements, List elements) { + + // Get the type of the element + XmlSchemaType elementType = element != null ? element.getSchemaType() : null; + + + // Confirm if the element is of Complex type + if (elementType instanceof XmlSchemaComplexType) { + // Get all particles associated with that element Type + XmlSchemaParticle allParticles = ((XmlSchemaComplexType) elementType).getParticle(); + + // Check particle belongs to which type + if ((allParticles instanceof XmlSchemaSequence)) { + // System.out.println("Sequence Schema Type"); + final XmlSchemaSequence xmlSchemaSequence = (XmlSchemaSequence) allParticles; + final List items = xmlSchemaSequence.getItems(); + + items.forEach((item) -> { + XmlSchemaElement itemElements = (XmlSchemaElement) item; + addChild(element.getQName(), itemElements, xsdElements); + elements.add(itemElements); + // Call method recursively to get all subsequent element + getChildElementNames(itemElements, xsdElements, elements); + }); + + } + // Check particle belongs to which type + if ((allParticles instanceof XmlSchemaChoice)) { + // System.out.println("Sequence Schema Type"); + final XmlSchemaChoice xmlSchemaSequence = (XmlSchemaChoice) allParticles; + final List items = xmlSchemaSequence.getItems(); + + items.forEach((item) -> { + XmlSchemaElement itemElements = (XmlSchemaElement) item; + addChild(element.getQName(), itemElements, xsdElements); + elements.add(itemElements); + // Call method recursively to get all subsequent element + getChildElementNames(itemElements, xsdElements, elements); + }); + + } + } + } + + // Add child elements based on its parent + private static void addChild(QName qName, XmlSchemaElement child, Map> xsdElements) { + List values = xsdElements.get(qName); + if (values == null) { + values = new ArrayList(); + } + values.add(child); + xsdElements.put(qName, values); + } + + public XmlView(Element element) { + super(element); + } + + public XmlView(Element element, URL xsdFile2) { + super(element); + this.xsdFile=xsdFile2; + } + + public void setSchema(URL xsdFile) { + this.xsdFile = xsdFile; + } +} \ No newline at end of file diff --git a/iped-app/src/main/java/iped/app/ui/controls/textarea/XmlViewFactory.java b/iped-app/src/main/java/iped/app/ui/controls/textarea/XmlViewFactory.java new file mode 100644 index 0000000000..a9220e8069 --- /dev/null +++ b/iped-app/src/main/java/iped/app/ui/controls/textarea/XmlViewFactory.java @@ -0,0 +1,26 @@ +package iped.app.ui.controls.textarea; + +import java.net.URL; + +import javax.swing.text.Element; +import javax.swing.text.View; +import javax.swing.text.ViewFactory; + +public class XmlViewFactory implements ViewFactory { + + URL xsdFile=null; + + /** + * @see javax.swing.text.ViewFactory#create(javax.swing.text.Element) + */ + public View create(Element element) { + XmlView xv = new XmlView(element, xsdFile); + xv.configPatterns(); + return xv; + } + + public void setSchema(URL xsdFile) { + this.xsdFile = xsdFile; + } + +} diff --git a/iped-app/src/main/java/iped/app/ui/themes/ThemeManager.java b/iped-app/src/main/java/iped/app/ui/themes/ThemeManager.java index d19f50d84f..4a80cf5abf 100644 --- a/iped-app/src/main/java/iped/app/ui/themes/ThemeManager.java +++ b/iped-app/src/main/java/iped/app/ui/themes/ThemeManager.java @@ -26,6 +26,7 @@ import bibliothek.extension.gui.dock.theme.EclipseTheme; import bibliothek.extension.gui.dock.theme.eclipse.EclipseColorScheme; +import iped.app.home.MainFrame; import iped.app.ui.App; public class ThemeManager { @@ -95,21 +96,24 @@ public void run() { UIManager.setLookAndFeel(UIManager.getLookAndFeel()); } catch (UnsupportedLookAndFeelException e) { } + updateUI(MainFrame.getInstance()); updateUI(App.get()); - App.get().dockingControl.putProperty(EclipseTheme.ECLIPSE_COLOR_SCHEME, new EclipseColorScheme() { - @Override - public void updateUI() { - super.updateUI(); - Theme t = getCurrentTheme(); - if (t != null) { - Map map = t.getDockSettings(); - for (String key : map.keySet()) { - setColor(key, map.get(key)); + if (App.get().dockingControl != null) { + App.get().dockingControl.putProperty(EclipseTheme.ECLIPSE_COLOR_SCHEME, new EclipseColorScheme() { + @Override + public void updateUI() { + super.updateUI(); + Theme t = getCurrentTheme(); + if (t != null) { + Map map = t.getDockSettings(); + for (String key : map.keySet()) { + setColor(key, map.get(key)); + } } } - } - }); - App.get().updateUI(true); + }); + App.get().updateUI(true); + } } }); diff --git a/iped-app/src/main/resources/iped/app/home/IPED-logo_lupa.png b/iped-app/src/main/resources/iped/app/home/IPED-logo_lupa.png new file mode 100644 index 0000000000..caec775a53 Binary files /dev/null and b/iped-app/src/main/resources/iped/app/home/IPED-logo_lupa.png differ diff --git a/iped-app/src/main/resources/iped/app/home/config.png b/iped-app/src/main/resources/iped/app/home/config.png new file mode 100644 index 0000000000..18f1f8e09f Binary files /dev/null and b/iped-app/src/main/resources/iped/app/home/config.png differ diff --git a/iped-app/src/main/resources/iped/app/home/logo_iped_azul.png b/iped-app/src/main/resources/iped/app/home/logo_iped_azul.png new file mode 100644 index 0000000000..2352e5d551 Binary files /dev/null and b/iped-app/src/main/resources/iped/app/home/logo_iped_azul.png differ diff --git a/iped-app/src/main/resources/iped/app/home/newcase.png b/iped-app/src/main/resources/iped/app/home/newcase.png new file mode 100644 index 0000000000..773cf60640 Binary files /dev/null and b/iped-app/src/main/resources/iped/app/home/newcase.png differ diff --git a/iped-app/src/main/resources/iped/app/home/opencase.png b/iped-app/src/main/resources/iped/app/home/opencase.png new file mode 100644 index 0000000000..c5339842eb Binary files /dev/null and b/iped-app/src/main/resources/iped/app/home/opencase.png differ diff --git a/iped-app/src/main/resources/iped/app/home/processmanager/plug-in.png b/iped-app/src/main/resources/iped/app/home/processmanager/plug-in.png new file mode 100644 index 0000000000..d04fece26d Binary files /dev/null and b/iped-app/src/main/resources/iped/app/home/processmanager/plug-in.png differ diff --git a/iped-app/src/main/resources/iped/app/home/processmanager/plug_error.png b/iped-app/src/main/resources/iped/app/home/processmanager/plug_error.png new file mode 100644 index 0000000000..98b3a1d785 Binary files /dev/null and b/iped-app/src/main/resources/iped/app/home/processmanager/plug_error.png differ diff --git a/iped-app/src/main/resources/iped/app/home/processmanager/pluged-in.png b/iped-app/src/main/resources/iped/app/home/processmanager/pluged-in.png new file mode 100644 index 0000000000..30264e826c Binary files /dev/null and b/iped-app/src/main/resources/iped/app/home/processmanager/pluged-in.png differ diff --git a/iped-app/src/main/resources/iped/app/home/processmanager/success.png b/iped-app/src/main/resources/iped/app/home/processmanager/success.png new file mode 100644 index 0000000000..2f0f0a327a Binary files /dev/null and b/iped-app/src/main/resources/iped/app/home/processmanager/success.png differ diff --git a/iped-app/src/main/resources/iped/app/home/search.png b/iped-app/src/main/resources/iped/app/home/search.png new file mode 100644 index 0000000000..267b3a9794 Binary files /dev/null and b/iped-app/src/main/resources/iped/app/home/search.png differ diff --git a/iped-app/src/main/resources/iped/app/ui/cursor-hand-icon.png b/iped-app/src/main/resources/iped/app/ui/cursor-hand-icon.png new file mode 100644 index 0000000000..d2e53e1370 Binary files /dev/null and b/iped-app/src/main/resources/iped/app/ui/cursor-hand-icon.png differ diff --git a/iped-carvers/iped-carvers-api/src/main/java/iped/carvers/api/CarverType.java b/iped-carvers/iped-carvers-api/src/main/java/iped/carvers/api/CarverType.java index f732bc388c..09bb459243 100644 --- a/iped-carvers/iped-carvers-api/src/main/java/iped/carvers/api/CarverType.java +++ b/iped-carvers/iped-carvers-api/src/main/java/iped/carvers/api/CarverType.java @@ -27,6 +27,8 @@ public class CarverType implements Serializable { boolean stopOnNextHeader = false; boolean hasFooter = false; boolean hasLengthRef = false; + boolean enabled = true; + public int id; @Override public boolean equals(Object o) { @@ -215,4 +217,20 @@ public boolean hasLengthRef() { return hasLengthRef; } + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + } \ No newline at end of file diff --git a/iped-engine/src/main/java/iped/engine/config/AbstractPropertiesConfigurable.java b/iped-engine/src/main/java/iped/engine/config/AbstractPropertiesConfigurable.java index 44109339d7..bbcaf9a0c2 100644 --- a/iped-engine/src/main/java/iped/engine/config/AbstractPropertiesConfigurable.java +++ b/iped-engine/src/main/java/iped/engine/config/AbstractPropertiesConfigurable.java @@ -6,10 +6,10 @@ import iped.configuration.Configurable; import iped.utils.UTF8Properties; -public abstract class AbstractPropertiesConfigurable implements Configurable { +public abstract class AbstractPropertiesConfigurable implements Configurable, IPropertiesConfigurable { /** - * + * */ private static final long serialVersionUID = 1L; protected UTF8Properties properties = new UTF8Properties(); @@ -30,6 +30,16 @@ public void processConfig(Path resource) throws IOException { processProperties(properties); } - abstract void processProperties(UTF8Properties properties); + public abstract void processProperties(UTF8Properties properties); + + public UTF8Properties getPropertie() { + return properties; + } + + @Override + public void reset() { + // TODO Auto-generated method stub + + } } diff --git a/iped-engine/src/main/java/iped/engine/config/AbstractTaskConfig.java b/iped-engine/src/main/java/iped/engine/config/AbstractTaskConfig.java index 79fe1f348a..daf35073e1 100644 --- a/iped-engine/src/main/java/iped/engine/config/AbstractTaskConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/AbstractTaskConfig.java @@ -45,12 +45,20 @@ public void processConfig(Path resource) throws IOException { @Override public boolean isEnabled() { - return enabledProp.isEnabled(); + return enabledProp!=null && enabledProp.isEnabled(); } @Override public void setEnabled(boolean enabled) { + if (enabledProp == null) { + enabledProp = new EnableTaskProperty(getTaskEnableProperty()); + } enabledProp.setEnabled(enabled); } + @Override + public void reset() { + + } + } diff --git a/iped-engine/src/main/java/iped/engine/config/AbstractTaskPropertiesConfig.java b/iped-engine/src/main/java/iped/engine/config/AbstractTaskPropertiesConfig.java index 69c688ebb5..018356c298 100644 --- a/iped-engine/src/main/java/iped/engine/config/AbstractTaskPropertiesConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/AbstractTaskPropertiesConfig.java @@ -1,11 +1,12 @@ package iped.engine.config; +import java.io.File; import java.io.IOException; import java.nio.file.Path; import iped.utils.UTF8Properties; -public abstract class AbstractTaskPropertiesConfig extends AbstractTaskConfig { +public abstract class AbstractTaskPropertiesConfig extends AbstractTaskConfig implements IPropertiesConfigurable { /** * @@ -29,6 +30,19 @@ public void processTaskConfig(Path resource) throws IOException { processProperties(properties); } - abstract void processProperties(UTF8Properties properties); + @Override + public abstract void processProperties(UTF8Properties properties); + + @Override + public void save(Path resource) { + try { + File confDir = new File(resource.toFile(), Configuration.CONF_DIR); + confDir.mkdirs(); + File confFile = new File(confDir, getTaskConfigFileName()); + properties.store(confFile); + }catch (Exception e) { + e.printStackTrace(); + } + } } diff --git a/iped-engine/src/main/java/iped/engine/config/AnalysisConfig.java b/iped-engine/src/main/java/iped/engine/config/AnalysisConfig.java index a2d753e78c..49284a6f98 100644 --- a/iped-engine/src/main/java/iped/engine/config/AnalysisConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/AnalysisConfig.java @@ -1,5 +1,6 @@ package iped.engine.config; +import java.io.File; import java.io.IOException; import java.nio.file.DirectoryStream; import java.nio.file.DirectoryStream.Filter; @@ -136,4 +137,16 @@ public int getOpenImagesCacheWarmUpThreads() { return openImagesCacheWarmUpThreads; } + @Override + public void save(Path resource) { + try { + File confDir = new File(resource.toFile(), Configuration.CONF_DIR); + confDir.mkdirs(); + File confFile = new File(confDir, CONFIG_FILE); + properties.store(confFile); + } catch (IOException e) { + e.printStackTrace(); + } + } + } diff --git a/iped-engine/src/main/java/iped/engine/config/CategoryConfig.java b/iped-engine/src/main/java/iped/engine/config/CategoryConfig.java index 7bb5601756..be287543e0 100644 --- a/iped-engine/src/main/java/iped/engine/config/CategoryConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/CategoryConfig.java @@ -1,6 +1,10 @@ package iped.engine.config; +import java.io.CharArrayReader; +import java.io.File; import java.io.IOException; +import java.io.Reader; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.HashMap; @@ -26,6 +30,7 @@ public class CategoryConfig extends AbstractTaskConfig { private static final String CONFIG_FILE = "CategoriesConfig.json"; private Category root; + private String json; private transient Map normalizedMap; @@ -85,30 +90,23 @@ public boolean isEnabled() { @Override public String getConfiguration() { - ObjectMapper objectMapper = new ObjectMapper(); - ObjectWriter writer = objectMapper.writerFor(Category.class); - try { - return writer.writeValueAsString(root); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } + return json; } @Override - public void setConfiguration(String config) { + public void setConfiguration(String json) { + this.json = json; ObjectMapper objectMapper = new ObjectMapper(); ObjectReader reader = objectMapper.readerFor(Category.class); try { - root = reader.readValue(config); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); + try (Reader in = new CharArrayReader(json.toCharArray()) ) { + root = reader.readValue(in); + populateParents(root); + } + }catch (Exception e) { + e.printStackTrace(); } - populateParents(root); - } - - public Category getRootCategory() { - return root; - } +} @Override public String getTaskEnableProperty() { @@ -122,7 +120,8 @@ public String getTaskConfigFileName() { @Override public void processTaskConfig(Path resource) throws IOException { - setConfiguration(Files.readString(resource)); + json = Files.readString(resource); + setConfiguration(json); } private void populateParents(Category category) { @@ -156,4 +155,21 @@ public Category getCategoryFromName(String categoryName) { return getNameToCategoryMap().get(categoryName); } + @Override + public void save(Path resource) { + try { + String output = ""; + File confDir = new File(resource.toFile(), Configuration.CONF_DIR); + confDir.mkdirs(); + File confFile = new File(confDir, CONFIG_FILE); + Files.write(confFile.toPath(),json.getBytes(StandardCharsets.UTF_8)); + }catch (Exception e) { + e.printStackTrace(); + } + } + + public Category getRoot() { + return root; + } + } diff --git a/iped-engine/src/main/java/iped/engine/config/CategoryToExpandConfig.java b/iped-engine/src/main/java/iped/engine/config/CategoryToExpandConfig.java index 1bdce25c6f..2118cb9d01 100644 --- a/iped-engine/src/main/java/iped/engine/config/CategoryToExpandConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/CategoryToExpandConfig.java @@ -1,7 +1,9 @@ package iped.engine.config; import java.io.BufferedReader; +import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collection; @@ -66,8 +68,6 @@ public void processTaskConfig(Path resource) throws IOException { categoriesToExpand.add(cat.getName()); cats.addAll(cat.getChildren()); } - - } } } @@ -82,4 +82,16 @@ public void setConfiguration(Set config) { categoriesToExpand = config; } + @Override + public void save(Path resource) { + try { + File confDir = new File(resource.toFile(), Configuration.CONF_DIR); + confDir.mkdirs(); + File confFile = new File(confDir, CONFIG_FILE); + Files.write(confFile.toPath(),categoriesToExpand); + }catch (Exception e) { + e.printStackTrace(); + } + } + } diff --git a/iped-engine/src/main/java/iped/engine/config/ConfigurableChangeListener.java b/iped-engine/src/main/java/iped/engine/config/ConfigurableChangeListener.java new file mode 100644 index 0000000000..7d6e486203 --- /dev/null +++ b/iped-engine/src/main/java/iped/engine/config/ConfigurableChangeListener.java @@ -0,0 +1,10 @@ +package iped.engine.config; + +import iped.configuration.Configurable; + +public interface ConfigurableChangeListener { + + void onChange(Configurable configurable); + + +} diff --git a/iped-engine/src/main/java/iped/engine/config/Configuration.java b/iped-engine/src/main/java/iped/engine/config/Configuration.java index af563565c7..b3a8d6c10d 100644 --- a/iped-engine/src/main/java/iped/engine/config/Configuration.java +++ b/iped-engine/src/main/java/iped/engine/config/Configuration.java @@ -35,6 +35,7 @@ import iped.configuration.Configurable; import iped.configuration.IConfigurationDirectory; import iped.engine.task.AbstractTask; +import iped.engine.task.IScriptTask; import iped.engine.util.Util; import iped.utils.UTF8Properties; import iped.viewers.util.DefaultPolicy; @@ -55,7 +56,7 @@ public class Configuration { private static Configuration singleton; private static AtomicBoolean loaded = new AtomicBoolean(); - private ConfigurationDirectory configDirectory; + private IConfigurationDirectory configDirectory; public Logger logger; public UTF8Properties properties = new UTF8Properties(); public String configPath, appRoot; @@ -71,7 +72,10 @@ public static Configuration getInstance() { return singleton; } - private Configuration() { + /** + * The config UI must have access to configuration constructor to create a specific configuration. + */ + public Configuration() { } private String getAppRoot(String configPath) { @@ -169,69 +173,80 @@ public void loadConfigurables(String configPathStr, boolean loadAll) throws IOEx logger.info("Loading configuration from " + configPath); //$NON-NLS-1$ } - configDirectory = new ConfigurationDirectory(Paths.get(appRoot, LOCAL_CONFIG)); + File configFile = new File(configPathStr); + ConfigurationManager configManager = null; + + if(configFile.isDirectory()) { + ConfigurationDirectory localconfigDirectory = new ConfigurationDirectory(Paths.get(appRoot, LOCAL_CONFIG)); + File defaultProfile = new File(appRoot); + File currentProfile = new File(configPathStr); + File caseProfile = new File(appRoot, CASE_PROFILE_DIR); + addProfileToConfigDirectory(localconfigDirectory, defaultProfile); + if (!currentProfile.equals(defaultProfile)) { + addProfileToConfigDirectory(localconfigDirectory, currentProfile); + } else if (caseProfile.exists()) { + addProfileToConfigDirectory(localconfigDirectory, caseProfile); + } + + configDirectory = localconfigDirectory; + configManager = ConfigurationManager.createInstance(configDirectory); - File defaultProfile = new File(appRoot); - File currentProfile = new File(configPathStr); - File caseProfile = new File(appRoot, CASE_PROFILE_DIR); - addProfileToConfigDirectory(configDirectory, defaultProfile); - if (!currentProfile.equals(defaultProfile)) { - addProfileToConfigDirectory(configDirectory, currentProfile); - } else if (caseProfile.exists()) { - addProfileToConfigDirectory(configDirectory, caseProfile); - } - ConfigurationManager configManager = ConfigurationManager.createInstance(configDirectory); - LocaleConfig lc = new LocaleConfig(); - configManager.addObject(lc); - configManager.loadConfig(lc); + configManager.addObject(new LocaleConfig()); - PluginConfig pluginConfig = new PluginConfig(); - configManager.addObject(pluginConfig); - configManager.loadConfig(pluginConfig); - addPluginJarsToConfigurationLookup(configDirectory, pluginConfig); + PluginConfig pluginConfig = new PluginConfig(); + configManager.addObject(pluginConfig); + configManager.loadConfig(pluginConfig); + if(configDirectory instanceof ConfigurationDirectory) { + addPluginJarsToConfigurationLookup((ConfigurationDirectory)configDirectory, pluginConfig); + } - configManager.addObject(new SplashScreenConfig()); - - if (!loadAll) { - configManager.loadConfigs(); - return; - } + configManager.addObject(new SplashScreenConfig()); + + if (!loadAll) { + configManager.loadConfigs(); + return; + } - loadNativeLibs(); + loadNativeLibs(); - configManager.addObject(new LocalConfig()); - configManager.addObject(new OCRConfig()); - configManager.addObject(new FileSystemConfig()); - configManager.addObject(new AnalysisConfig()); + configManager.addObject(new LocalConfig()); + configManager.addObject(new OCRConfig()); + configManager.addObject(new FileSystemConfig()); + configManager.addObject(new AnalysisConfig()); - TaskInstallerConfig taskConfig = new TaskInstallerConfig(); - configManager.addObject(taskConfig); + TaskInstallerConfig taskConfig = new TaskInstallerConfig(); + configManager.addObject(taskConfig); - // must load taskConfig before using it - configManager.loadConfig(taskConfig); + // must load taskConfig before using it + configManager.loadConfig(taskConfig); - for (AbstractTask task : taskConfig.getNewTaskInstances()) { - for (Configurable configurable : task.getConfigurables()) { - configManager.addObject(configurable); + for (AbstractTask task : taskConfig.getNewTaskInstances()) { + for (Configurable configurable : task.getConfigurables()) { + configManager.addObject(configurable); + } } - } - - configManager.loadConfigs(); + configManager.loadConfigs(); - // blocks internet access from html viewers - DefaultPolicy policy = new DefaultPolicy(); - MinIOConfig minIOConfig = configManager.findObject(MinIOConfig.class); - if (minIOConfig.isEnabled()) { - String host = minIOConfig.getHostAndPort(); - if (host.startsWith("http://") || host.startsWith("https://")) { - host = host.substring(host.indexOf("://") + 3); + // blocks internet access from html viewers + DefaultPolicy policy = new DefaultPolicy(); + MinIOConfig minIOConfig = configManager.findObject(MinIOConfig.class); + if (minIOConfig.isEnabled()) { + String host = minIOConfig.getHostAndPort(); + if (host.startsWith("http://") || host.startsWith("https://")) { + host = host.substring(host.indexOf("://") + 3); + } + policy.addAllowedPermission(new SocketPermission(host, "connect,resolve")); } - policy.addAllowedPermission(new SocketPermission(host, "connect,resolve")); + Policy.setPolicy(policy); + System.setSecurityManager(new SecurityManager()); + + }else { + configDirectory = new SerializedConfigurationDirectory(configFile.toPath()); + configManager = ConfigurationManager.createInstance(configDirectory); + configManager.loadConfigs(true); } - Policy.setPolicy(policy); - System.setSecurityManager(new SecurityManager()); } // add plugin jars to the configuration resource look up engine diff --git a/iped-engine/src/main/java/iped/engine/config/ConfigurationDirectory.java b/iped-engine/src/main/java/iped/engine/config/ConfigurationDirectory.java index cfc0581d6f..876e19a4a7 100644 --- a/iped-engine/src/main/java/iped/engine/config/ConfigurationDirectory.java +++ b/iped-engine/src/main/java/iped/engine/config/ConfigurationDirectory.java @@ -20,9 +20,10 @@ import iped.configuration.Configurable; import iped.configuration.IConfigurationDirectory; -public class ConfigurationDirectory implements IConfigurationDirectory { +public class ConfigurationDirectory implements IConfigurationDirectory, Comparable { List configDirs = new ArrayList(); + String name; public ConfigurationDirectory(Path configDir) { configDirs.add(configDir); @@ -94,7 +95,24 @@ public boolean test(Path path) { } } }); + } + @Override + public String getName() { + return name; } + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return getName(); + } + + @Override + public int compareTo(IConfigurationDirectory o) { + return this.getName().compareTo(o.getName()); + } } diff --git a/iped-engine/src/main/java/iped/engine/config/ConfigurationManager.java b/iped-engine/src/main/java/iped/engine/config/ConfigurationManager.java index 8a92328688..e83a9504d1 100644 --- a/iped-engine/src/main/java/iped/engine/config/ConfigurationManager.java +++ b/iped-engine/src/main/java/iped/engine/config/ConfigurationManager.java @@ -1,5 +1,6 @@ package iped.engine.config; +import java.io.EOFException; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -7,12 +8,16 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.lang.reflect.InvocationTargetException; import java.nio.file.Path; +import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import iped.configuration.Configurable; @@ -20,58 +25,137 @@ import iped.configuration.ObjectManager; public class ConfigurationManager implements ObjectManager> { - - private static ConfigurationManager singleton = null; + private static ConfigurationManager selectedCM = null; + List configurableChangeListeners = new ArrayList(); private IConfigurationDirectory directory; - private Map, Boolean> loadedConfigurables = new LinkedHashMap<>(); + + class ConfigurableWrapper{ + Configurable c; + + public ConfigurableWrapper(Configurable config) { + this.c = config; + } + @Override + public int hashCode() { + if(c instanceof EnableTaskProperty) { + return Objects.hash(c.getClass(), ((EnableTaskProperty)c).getPropertyName()); + } + return c.getClass().hashCode(); + } + + @Override + public boolean equals(Object o) { + if(c instanceof EnableTaskProperty) { + return c.getClass().equals(((ConfigurableWrapper)o).c.getClass()) && ((EnableTaskProperty) c).getPropertyName().equals(((EnableTaskProperty) ((ConfigurableWrapper)o).c).getPropertyName()); + } + if(c instanceof DefaultTaskPropertiesConfig) { + return c.getClass().equals(((ConfigurableWrapper)o).c.getClass()) && ((DefaultTaskPropertiesConfig) c).getTaskConfigFileName().equals(((DefaultTaskPropertiesConfig) ((ConfigurableWrapper)o).c).getTaskConfigFileName()); + } + return c.getClass().equals(((ConfigurableWrapper)o).c.getClass()); + } + + } + + private Map loadedConfigurablesState = new LinkedHashMap<>(); + + boolean changed=false; + + /** + * @return returns current selected configuration profile + */ public static ConfigurationManager get() { - return singleton; + return selectedCM; } + public static void setCurrentConfigurationManager(ConfigurationManager cm) { + selectedCM = cm; + } + + /** + * Creates an ConfigurationManager instance an sets it as the current selected CM. + */ public static ConfigurationManager createInstance(IConfigurationDirectory directory) { - if (singleton == null) { + if (selectedCM == null) { synchronized (ConfigurationManager.class) { - if (singleton == null) { - singleton = new ConfigurationManager(directory); + if (selectedCM == null) { + selectedCM = new ConfigurationManager(directory); } } } - return singleton; + return selectedCM; } - private ConfigurationManager(IConfigurationDirectory directory) { + public ConfigurationManager(IConfigurationDirectory directory) { this.directory = directory; } @Override public void addObject(Configurable config) { - loadedConfigurables.put(config, false); + loadedConfigurablesState.put(new ConfigurableWrapper(config), false); } public void loadConfigs() throws IOException { - for (Iterator> iterator = loadedConfigurables.keySet().iterator(); iterator.hasNext();) { - Configurable configurable = iterator.next(); + ConfigurableWrapper[] array = loadedConfigurablesState.keySet().toArray(new ConfigurableWrapper[0]); + for (int i=0; i< array.length; i++) { + Configurable configurable = array[i].c; loadConfig(configurable); } } - public void loadConfig(Configurable configurable) throws IOException { - if (loadedConfigurables.get(configurable) == false) { + public void loadConfig(Configurable configurable, boolean forceReload) throws IOException { + Boolean loaded = loadedConfigurablesState.get(new ConfigurableWrapper(configurable)); + if (forceReload || loaded ==null || loaded == false) { List resources = directory.lookUpResource(configurable); - configurable.processConfigs(resources); - loadedConfigurables.put(configurable, true); - } + if(resources!=null) { + configurable.processConfigs(resources); + } + ConfigurableWrapper cw = new ConfigurableWrapper(configurable); + loadedConfigurablesState.remove(cw); + loadedConfigurablesState.put(cw , true); + } + } + + public void loadConfig(Configurable configurable) throws IOException { + loadConfig(configurable,false); } public void loadConfigs(boolean forceReload) throws IOException { - for (Iterator> iterator = loadedConfigurables.keySet().iterator(); iterator.hasNext();) { - Configurable configurable = iterator.next(); + if(directory instanceof ConfigurationDirectory) { + for (Iterator iterator = loadedConfigurablesState.keySet().iterator(); iterator.hasNext();) { + Configurable configurable = iterator.next().c; + if(forceReload) { + configurable.reset(); + } - List resources = directory.lookUpResource(configurable); + List resources = directory.lookUpResource(configurable); - configurable.processConfigs(resources); + configurable.processConfigs(resources); + } + }else if(directory instanceof SerializedConfigurationDirectory) { + ObjectInputStream ois = ((SerializedConfigurationDirectory) directory).openInputStream(); + try { + Configurable configurable=(Configurable)ois.readObject(); + while(configurable!=null) { + ConfigurableWrapper cw = new ConfigurableWrapper(configurable); + loadedConfigurablesState.remove(cw); + loadedConfigurablesState.put(cw, true); + try { + configurable=(Configurable)ois.readObject(); + }catch (EOFException e) { + configurable=null; + } + } + } catch (ClassNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + }finally { + ois.close(); + } } } @@ -83,9 +167,9 @@ public IConfigurationDirectory getConfigurationDirectory() { public Set> findObjects(Class> clazz) { Set> result = new HashSet<>(); - for (Iterator> iterator = loadedConfigurables.keySet().iterator(); iterator.hasNext();) { - Configurable configurable = iterator.next(); - if (configurable.getClass().equals(clazz)) { + for (Iterator iterator = loadedConfigurablesState.keySet().iterator(); iterator.hasNext();) { + Configurable configurable = iterator.next().c; + if (clazz.isInstance(configurable)) { result.add(configurable); } } @@ -94,18 +178,18 @@ public Set> findObjects(Class> clazz) } public > T findObject(Class> clazz) { - for (Configurable configurable : singleton.loadedConfigurables.keySet()) { - if (configurable.getClass().equals(clazz)) { - return (T) configurable; + for (ConfigurableWrapper configurablew : loadedConfigurablesState.keySet()) { + if (configurablew.c.getClass().equals(clazz)) { + return (T) configurablew.c; } } return null; } public AbstractTaskConfig getTaskConfigurable(String configFileName) { - for (Configurable config : singleton.loadedConfigurables.keySet()) { - if (config instanceof AbstractTaskConfig) { - AbstractTaskConfig taskConfig = (AbstractTaskConfig) config; + for (ConfigurableWrapper configw : loadedConfigurablesState.keySet()) { + if (configw.c instanceof AbstractTaskConfig) { + AbstractTaskConfig taskConfig = (AbstractTaskConfig) configw.c; if (taskConfig.getTaskConfigFileName().equals(configFileName)) { return taskConfig; } @@ -126,7 +210,7 @@ public EnableTaskProperty getEnableTaskConfigurable(String propertyName) { } public boolean getEnableTaskProperty(String propertyName) { - EnableTaskProperty enableProp = singleton.getEnableTaskConfigurable(propertyName); + EnableTaskProperty enableProp = getEnableTaskConfigurable(propertyName); if (enableProp != null) { return enableProp.isEnabled(); } else { @@ -134,12 +218,16 @@ public boolean getEnableTaskProperty(String propertyName) { } } + public EnableTaskProperty getEnableTaskPropertyObject(String propertyName) { + return getEnableTaskConfigurable(propertyName); + } + @Override public Set> findObjects(String className) { Set> result = new HashSet<>(); - for (Iterator> iterator = loadedConfigurables.keySet().iterator(); iterator.hasNext();) { - Configurable configurable = iterator.next(); + for (Iterator iterator = loadedConfigurablesState.keySet().iterator(); iterator.hasNext();) { + Configurable configurable = iterator.next().c; if (configurable.getClass().getName().equals(className)) { result.add(configurable); } @@ -150,18 +238,24 @@ public Set> findObjects(String className) { @Override public Set> getObjects() { - return loadedConfigurables.keySet(); + LinkedHashSet> result = new LinkedHashSet>(); + for (Iterator iterator = loadedConfigurablesState.keySet().iterator(); iterator.hasNext();) { + ConfigurableWrapper configurablew = (ConfigurableWrapper) iterator.next(); + result.add(configurablew.c); + + } + return result; } @Override public void removeObject(Configurable aObject) { - loadedConfigurables.remove(aObject); + loadedConfigurablesState.remove(new ConfigurableWrapper(aObject)); } - + public void saveSerializedConfig(File file) throws FileNotFoundException, IOException { try(FileOutputStream fos = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(fos)){ - oos.writeObject(loadedConfigurables); + oos.writeObject(loadedConfigurablesState); } } @@ -169,7 +263,77 @@ public void saveSerializedConfig(File file) throws FileNotFoundException, IOExce public void loadSerializedConfig(File file) throws FileNotFoundException, IOException, ClassNotFoundException { try (FileInputStream fis = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(fis)) { - loadedConfigurables = (Map, Boolean>) ois.readObject(); + loadedConfigurablesState = (Map) ois.readObject(); + } + } +/* + public void saveConfigurables() { + for (Iterator> iterator = changedConfigurable.iterator(); iterator.hasNext();) { + Configurable config = iterator.next(); + + try { + Writer w = null; + try { + List resources = directory.lookUpResource(config); + for (Iterator iterator2 = resources.iterator(); iterator2.hasNext();) { + Path path = (Path) iterator2.next(); + config.save(path); + } + }finally { + if(w!=null) { + w.close(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } +*/ + + public IConfigurationDirectory getDirectory() { + return directory; + } + + public void setDirectory(IConfigurationDirectory directory) { + this.directory = directory; + } + + public void notifyUpdate(Configurable configurable) { + for (Iterator iterator = configurableChangeListeners.iterator(); iterator.hasNext();) { + ConfigurableChangeListener ccl = iterator.next(); + ccl.onChange(configurable); + } + changed=true; + } + + public boolean hasChanged() { + return changed; + } + + public void addConfigurableChangeListener(ConfigurableChangeListener ccl) { + configurableChangeListeners.add(ccl); + } + + public void removeConfigurableChangeListener(ConfigurableChangeListener ccl) { + configurableChangeListeners.remove(ccl); + } + + /** + * A method to refresh the changed configurable properties values + * First whe change the old instance on loadedConfigurables by the new one + * so whe call LoadConfig method to reload the new propertie + * @param clazz - Configurable Class + */ + public void reloadConfigurable(Class> clazz){ + try { + removeObject(get().findObject(clazz)); + Class[] empty = {}; + Configurable configurable = clazz.getConstructor(empty).newInstance(); + addObject(configurable); + loadConfig(configurable); + } catch (IOException | NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException ex) { + ex.printStackTrace(); } } diff --git a/iped-engine/src/main/java/iped/engine/config/DefaultTaskPropertiesConfig.java b/iped-engine/src/main/java/iped/engine/config/DefaultTaskPropertiesConfig.java index 1d29d6f282..7f3f2a9a33 100644 --- a/iped-engine/src/main/java/iped/engine/config/DefaultTaskPropertiesConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/DefaultTaskPropertiesConfig.java @@ -29,7 +29,7 @@ public String getTaskConfigFileName() { @Override public void processProperties(UTF8Properties properties) { - // no op + this.properties.putAll(properties); } } diff --git a/iped-engine/src/main/java/iped/engine/config/DocThumbTaskConfig.java b/iped-engine/src/main/java/iped/engine/config/DocThumbTaskConfig.java index 91a8a243ca..59525d7e9d 100644 --- a/iped-engine/src/main/java/iped/engine/config/DocThumbTaskConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/DocThumbTaskConfig.java @@ -1,5 +1,8 @@ package iped.engine.config; +import java.io.IOException; +import java.nio.file.Path; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/iped-engine/src/main/java/iped/engine/config/EnableTaskProperty.java b/iped-engine/src/main/java/iped/engine/config/EnableTaskProperty.java index f85fae796b..3176e90979 100644 --- a/iped-engine/src/main/java/iped/engine/config/EnableTaskProperty.java +++ b/iped-engine/src/main/java/iped/engine/config/EnableTaskProperty.java @@ -1,5 +1,6 @@ package iped.engine.config; +import java.io.File; import java.io.IOException; import java.nio.file.DirectoryStream.Filter; import java.nio.file.Path; @@ -8,7 +9,6 @@ import iped.utils.UTF8Properties; public class EnableTaskProperty extends AbstractPropertiesConfigurable implements EnabledInterface { - /** * */ @@ -56,4 +56,16 @@ public void setEnabled(boolean enabled) { this.value = enabled; } -} + @Override + public void save(Path resource) { + try { + File confFile = new File(resource.toFile(), Configuration.CONFIG_FILE); + properties.load(confFile); + properties.setProperty(propertyName, Boolean.toString(value)); + properties.store(confFile); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/iped-engine/src/main/java/iped/engine/config/ExportByCategoriesConfig.java b/iped-engine/src/main/java/iped/engine/config/ExportByCategoriesConfig.java index 24d35daf93..e507ee306b 100644 --- a/iped-engine/src/main/java/iped/engine/config/ExportByCategoriesConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/ExportByCategoriesConfig.java @@ -1,5 +1,6 @@ package iped.engine.config; +import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -62,4 +63,16 @@ public void processTaskConfig(Path resource) throws IOException { } } + @Override + public void save(Path resource) { + try { + File confDir = new File(resource.toFile(), Configuration.CONF_DIR); + confDir.mkdirs(); + File confFile = new File(confDir, CONFIG_FILE); + Files.write(confFile.toPath(),categoriesToExport); + }catch (Exception e) { + e.printStackTrace(); + } + } + } diff --git a/iped-engine/src/main/java/iped/engine/config/ExportByKeywordsConfig.java b/iped-engine/src/main/java/iped/engine/config/ExportByKeywordsConfig.java index ac32e78cba..e868b95e9f 100644 --- a/iped-engine/src/main/java/iped/engine/config/ExportByKeywordsConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/ExportByKeywordsConfig.java @@ -1,10 +1,12 @@ package iped.engine.config; import java.io.Externalizable; +import java.io.File; import java.io.IOException; import java.io.InvalidClassException; import java.io.ObjectInput; import java.io.ObjectOutput; +import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; @@ -33,16 +35,21 @@ public List getKeywords() { @Override public void processTaskConfig(Path resource) throws IOException { - - String content = Util.readUTF8Content(resource.toFile()); - for (String line : content.split("\n")) { //$NON-NLS-1$ - line = line.trim(); - if (line.startsWith("#") || line.isEmpty()) { //$NON-NLS-1$ - continue; + String content = null; + try { + content = Util.readUTF8Content(resource.toFile()); + }catch (ArrayIndexOutOfBoundsException e) { + + } + if(content!=null) { + for (String line : content.split("\n")) { //$NON-NLS-1$ + line = line.trim(); + if (line.startsWith("#") || line.isEmpty()) { //$NON-NLS-1$ + continue; + } + keywords.add(line); } - keywords.add(line); } - } @Override @@ -87,4 +94,16 @@ public void writeExternal(ObjectOutput out) throws IOException { } } + @Override + public void save(Path resource) { + try { + File confDir = new File(resource.toFile(), Configuration.CONF_DIR); + confDir.mkdirs(); + File confFile = new File(confDir, CONFIG_FILE); + Files.write(confFile.toPath(),keywords); + }catch (Exception e) { + e.printStackTrace(); + } + } + } diff --git a/iped-engine/src/main/java/iped/engine/config/ExternalParsersConfig.java b/iped-engine/src/main/java/iped/engine/config/ExternalParsersConfig.java index 9846fa6f45..cffab3cdee 100644 --- a/iped-engine/src/main/java/iped/engine/config/ExternalParsersConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/ExternalParsersConfig.java @@ -1,5 +1,6 @@ package iped.engine.config; +import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.DirectoryStream.Filter; @@ -58,4 +59,22 @@ public synchronized String getTmpConfigFilePath() { return tmp.toFile().getAbsolutePath(); } + @Override + public void save(Path resource) { + try { + File confDir = new File(resource.toFile(), Configuration.CONF_DIR); + confDir.mkdirs(); + File confFile = new File(confDir, EXTERNAL_PARSERS); + + Files.write(confFile.toPath(), externalParsersXml.getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void reset() { + // TODO Auto-generated method stub + } + } \ No newline at end of file diff --git a/iped-engine/src/main/java/iped/engine/config/FileSystemConfig.java b/iped-engine/src/main/java/iped/engine/config/FileSystemConfig.java index b2fc2e2035..b1cc220fab 100644 --- a/iped-engine/src/main/java/iped/engine/config/FileSystemConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/FileSystemConfig.java @@ -1,5 +1,6 @@ package iped.engine.config; +import java.io.File; import java.io.IOException; import java.nio.file.DirectoryStream.Filter; import java.nio.file.Path; @@ -18,7 +19,7 @@ public class FileSystemConfig extends AbstractPropertiesConfigurable { private boolean toAddUnallocated = false; private boolean toAddFileSlacks = false; private boolean robustImageReading; - private int numImageReaders = (int) Math.ceil((float) Runtime.getRuntime().availableProcessors() / 4); + private int numImageReaders = getDefaultNumImageReaders(); private long unallocatedFragSize = 1 << 30; private long minOrphanSizeToIgnore = -1; private boolean ignoreHardLinks = true; @@ -110,5 +111,21 @@ public long getMinOrphanSizeToIgnore() { public boolean isIgnoreHardLinks() { return ignoreHardLinks; } + + public int getDefaultNumImageReaders() { + return (int) Math.ceil((float) Runtime.getRuntime().availableProcessors() / 4); + } + + @Override + public void save(Path resource) { + try { + File confDir = new File(resource.toFile(), Configuration.CONF_DIR); + confDir.mkdirs(); + File confFile = new File(confDir, CONFIG_FILE); + properties.store(confFile); + }catch (Exception e) { + e.printStackTrace(); + } + } } diff --git a/iped-engine/src/main/java/iped/engine/config/HashDBLookupConfig.java b/iped-engine/src/main/java/iped/engine/config/HashDBLookupConfig.java index 3a9ed7c456..3fc5c447ec 100644 --- a/iped-engine/src/main/java/iped/engine/config/HashDBLookupConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/HashDBLookupConfig.java @@ -1,5 +1,6 @@ package iped.engine.config; +import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.DirectoryStream.Filter; @@ -56,7 +57,6 @@ public boolean accept(Path entry) throws IOException { @Override public void processTaskConfig(Path resource) throws IOException { - if (resource.endsWith(CONFIG_FILE)) { UTF8Properties properties = new UTF8Properties(); properties.load(resource.toFile()); @@ -67,7 +67,6 @@ public void processTaskConfig(Path resource) throws IOException { } else if (resource.endsWith(NSRL_CONFIG_FILE)) { this.nsrlConfig = new String(Files.readAllBytes(resource), StandardCharsets.UTF_8); } - } public boolean isExcludeKnown() { @@ -89,4 +88,25 @@ public void setConfiguration(Pair config) { this.nsrlConfig = config.getRight(); } + @Override + public void save(Path resource) { + try { + File confDir = new File(resource.toFile(), Configuration.CONF_DIR); + confDir.mkdirs(); + + if (resource.endsWith(CONFIG_FILE)) { + File confFile = new File(confDir, CONFIG_FILE); + UTF8Properties properties = new UTF8Properties(); + properties.load(resource.toFile()); + properties.setProperty(EXCLUDE_KNOWN, Boolean.toString(excludeKnown)); + properties.store(confFile); + } else if (resource.endsWith(NSRL_CONFIG_FILE)) { + File confFile = new File(confDir, NSRL_CONFIG_FILE); + Files.write(confFile.toPath(),this.nsrlConfig.getBytes(StandardCharsets.UTF_8)); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } diff --git a/iped-engine/src/main/java/iped/engine/config/HashTaskConfig.java b/iped-engine/src/main/java/iped/engine/config/HashTaskConfig.java index 9356a1b6bc..15c2a133aa 100644 --- a/iped-engine/src/main/java/iped/engine/config/HashTaskConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/HashTaskConfig.java @@ -41,5 +41,4 @@ public void processProperties(UTF8Properties properties) { } } - } diff --git a/iped-engine/src/main/java/iped/engine/config/HtmlReportTaskConfig.java b/iped-engine/src/main/java/iped/engine/config/HtmlReportTaskConfig.java index f2866f811b..7c97f38bc7 100644 --- a/iped-engine/src/main/java/iped/engine/config/HtmlReportTaskConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/HtmlReportTaskConfig.java @@ -178,5 +178,4 @@ public void processProperties(UTF8Properties properties) { info.reportTitle = properties.getProperty("Title"); //$NON-NLS-1$ } - } diff --git a/iped-engine/src/main/java/iped/engine/config/IPropertiesConfigurable.java b/iped-engine/src/main/java/iped/engine/config/IPropertiesConfigurable.java new file mode 100644 index 0000000000..b912817b53 --- /dev/null +++ b/iped-engine/src/main/java/iped/engine/config/IPropertiesConfigurable.java @@ -0,0 +1,9 @@ +package iped.engine.config; + +import iped.utils.UTF8Properties; + +public interface IPropertiesConfigurable { + + void processProperties(UTF8Properties properties); + +} \ No newline at end of file diff --git a/iped-engine/src/main/java/iped/engine/config/IndexTaskConfig.java b/iped-engine/src/main/java/iped/engine/config/IndexTaskConfig.java index e2da1e750f..bac6002b67 100644 --- a/iped-engine/src/main/java/iped/engine/config/IndexTaskConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/IndexTaskConfig.java @@ -172,5 +172,4 @@ public int getMaxTokenLength() { public int getCommitIntervalSeconds() { return commitIntervalSeconds; } - } diff --git a/iped-engine/src/main/java/iped/engine/config/LocalConfig.java b/iped-engine/src/main/java/iped/engine/config/LocalConfig.java index bb2c5c7295..81d08e2b37 100644 --- a/iped-engine/src/main/java/iped/engine/config/LocalConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/LocalConfig.java @@ -27,15 +27,15 @@ public class LocalConfig extends AbstractPropertiesConfigurable { public static final String NUM_THREADS = "numThreads"; - private static final String HASH_DB = "hashesDB"; + public static final String HASH_DB = "hashesDB"; - private static final String IPED_TEMP = "indexTemp"; + public static final String IPED_TEMP = "indexTemp"; private static final String TEMP_ON_SSD = "indexTempOnSSD"; - private static final String OUTPUT_ON_SSD = "outputOnSSD"; + public static final String OUTPUT_ON_SSD = "outputOnSSD"; - private static final String DEFAULT_VAL = "default"; + public static final String DEFAULT_VAL = "default"; public static final DirectoryStream.Filter filter = new Filter() { @Override @@ -107,7 +107,7 @@ public void processProperties(UTF8Properties properties) { if (value != null && !value.equalsIgnoreCase(DEFAULT_VAL)) { // $NON-NLS-1$ numThreads = Integer.valueOf(value); } else { - numThreads = Runtime.getRuntime().availableProcessors(); + numThreads = getDefaultNumThreads(); } value = properties.getProperty(TEMP_ON_SSD); // $NON-NLS-1$ @@ -149,6 +149,11 @@ public boolean isIndexTempOnSSD() { return indexTempOnSSD; } + public void setIndexTempOnSSD(Boolean indexTempOnSSD){ + properties.setProperty(TEMP_ON_SSD, Boolean.valueOf(indexTempOnSSD).toString()); + this.indexTempOnSSD = Boolean.valueOf(indexTempOnSSD); + } + public File getIndexTemp() { return indexTemp; } @@ -161,6 +166,26 @@ public int getNumThreads() { return numThreads; } + public void setNumThreads(Object numThreads) { + if (numThreads instanceof Integer) { + setNumThreads(((Integer) numThreads).intValue()); + return; + } else { + if (numThreads instanceof String) { + if (numThreads.equals(DEFAULT_VAL)) { + properties.setProperty(NUM_THREADS, DEFAULT_VAL); + return; + } + } + } + } + + public void setNumThreads(int numThreads){ + this.numThreads = numThreads; + String stringValue = (numThreads == Runtime.getRuntime().availableProcessors()) ? DEFAULT_VAL : String.valueOf(numThreads); + properties.setProperty(NUM_THREADS, stringValue); + } + public File getHashDbFile() { return hashDbFile; } @@ -168,7 +193,7 @@ public File getHashDbFile() { public void setHashDbFile(File hashDbFile) { this.hashDbFile = hashDbFile; } - + public static void clearLocalParameters(File localConfig) throws IOException { List lines = Files.readAllLines(localConfig.toPath()); ArrayList newLines = new ArrayList<>(); @@ -189,4 +214,21 @@ public static void clearLocalParameters(File localConfig) throws IOException { } Files.write(localConfig.toPath(), newLines); } + + @Override + public void save(Path resource) { + try { + File confDir = new File(resource.toFile(), Configuration.CONF_DIR); + confDir.mkdirs(); + File confFile = new File(confDir, CONFIG_FILE); + properties.store(confFile); + }catch (Exception e) { + e.printStackTrace(); + } + } + + public int getDefaultNumThreads() { + return Runtime.getRuntime().availableProcessors(); + } + } diff --git a/iped-engine/src/main/java/iped/engine/config/LocaleConfig.java b/iped-engine/src/main/java/iped/engine/config/LocaleConfig.java index a8b837b0b0..b75be952a2 100644 --- a/iped-engine/src/main/java/iped/engine/config/LocaleConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/LocaleConfig.java @@ -1,5 +1,6 @@ package iped.engine.config; +import java.io.File; import java.io.IOException; import java.nio.file.DirectoryStream; import java.nio.file.DirectoryStream.Filter; @@ -11,11 +12,12 @@ public class LocaleConfig extends AbstractPropertiesConfigurable { /** - * + * */ private static final long serialVersionUID = 1L; public static final String CONFIG_FILE = "LocalConfig.txt"; //$NON-NLS-1$ private static final String HOST_COUNTRY = "hostCountryCode"; + private static final String LOCALE = "locale"; public static final DirectoryStream.Filter filter = new Filter() { @Override @@ -45,17 +47,33 @@ public Filter getResourceLookupFilter() { @Override public void processProperties(UTF8Properties properties) { - String value; + value = properties.getProperty(LOCALE); + setLocale(value); + } - value = properties.getProperty("locale"); //$NON-NLS-1$ + public void setLocale(String value){ if (value != null && !value.trim().isEmpty()) locale = Locale.forLanguageTag(value.trim()); - System.setProperty(iped.localization.Messages.LOCALE_SYS_PROP, locale.toLanguageTag()); // $NON-NLS-1$ + properties.setProperty(LOCALE, value); + System.setProperty(iped.localization.Messages.LOCALE_SYS_PROP, locale.toLanguageTag()); } public Locale getLocale() { return locale; } + + @Override + public void save(Path resource) { + try { + File confDir = new File(resource.toFile(), Configuration.CONF_DIR); + confDir.mkdirs(); + File confFile = new File(confDir, CONFIG_FILE); + properties.store(confFile); + }catch (Exception e) { + e.printStackTrace(); + } + } + } diff --git a/iped-engine/src/main/java/iped/engine/config/MakePreviewConfig.java b/iped-engine/src/main/java/iped/engine/config/MakePreviewConfig.java index 8ce0d31e85..572d9b8671 100644 --- a/iped-engine/src/main/java/iped/engine/config/MakePreviewConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/MakePreviewConfig.java @@ -1,9 +1,13 @@ package iped.engine.config; +import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Set; @@ -76,4 +80,34 @@ else if (line.startsWith(SUPPORTED_KEY)) } + @Override + public void save(Path resource) { + try { + StringBuffer output = new StringBuffer(); + output.append(SUPPORTED_KEY+"="); + for (Iterator iterator = supportedMimes.iterator(); iterator.hasNext();) { + String string = (String) iterator.next(); + output.append(string); + if(iterator.hasNext()) { + output.append(";"); + } + } + output.append(SUPPORTED_LINKS_KEY+"="); + for (Iterator iterator = supportedMimesWithLinks.iterator(); iterator.hasNext();) { + String string = (String) iterator.next(); + output.append(string); + if(iterator.hasNext()) { + output.append(";"); + } + } + File confDir = new File(resource.toFile(), Configuration.CONF_DIR); + confDir.mkdirs(); + File confFile = new File(confDir, CONFIG_FILE); + + Files.write(confFile.toPath(),output.toString().getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + e.printStackTrace(); + } + } + } diff --git a/iped-engine/src/main/java/iped/engine/config/MinIOConfig.java b/iped-engine/src/main/java/iped/engine/config/MinIOConfig.java index 42cc9f5da5..2e7bd87079 100644 --- a/iped-engine/src/main/java/iped/engine/config/MinIOConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/MinIOConfig.java @@ -84,5 +84,4 @@ public int getRetries() { return retries; } - } diff --git a/iped-engine/src/main/java/iped/engine/config/OCRConfig.java b/iped-engine/src/main/java/iped/engine/config/OCRConfig.java index a05e73d099..1d76fd514c 100644 --- a/iped-engine/src/main/java/iped/engine/config/OCRConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/OCRConfig.java @@ -1,20 +1,22 @@ package iped.engine.config; +import java.io.File; import java.io.IOException; import java.nio.file.DirectoryStream; import java.nio.file.DirectoryStream.Filter; import java.nio.file.Path; +import iped.configuration.EnabledInterface; import iped.utils.UTF8Properties; -public class OCRConfig extends AbstractPropertiesConfigurable { +public class OCRConfig extends AbstractPropertiesConfigurable implements EnabledInterface { /** * */ private static final long serialVersionUID = 1L; private static final String CONFIG_FILE0 = "IPEDConfig.txt"; //$NON-NLS-1$ - public static final String CONFIG_FILE = "conf/OCRConfig.txt"; //$NON-NLS-1$ + public static final String CONFIG_FILE = "OCRConfig.txt"; //$NON-NLS-1$ private Boolean enableOCR; private boolean skipKnownFiles; @@ -45,7 +47,9 @@ public Filter getResourceLookupFilter() { @Override public void processProperties(UTF8Properties properties) { - String value = properties.getProperty("enableOCR"); //$NON-NLS-1$ + String value; + + value = properties.getProperty("enableOCR"); //$NON-NLS-1$ if (value != null && !value.trim().isEmpty()) { if (Boolean.valueOf(value.trim())) { enableOCR = true; @@ -55,7 +59,7 @@ public void processProperties(UTF8Properties properties) { } else if (enableOCR == null) { enableOCR = false; } - + value = properties.getProperty("OCRLanguage"); //$NON-NLS-1$ if (value != null && !value.trim().isEmpty()) { ocrLanguage = value.trim(); @@ -170,4 +174,47 @@ public String getMaxConvImageSize() { return maxConvImageSize; } + @Override + public void save(Path resource) { + try { + File confDir = new File(resource.toFile(), Configuration.CONF_DIR); + confDir.mkdirs(); + File confFile = new File(confDir, CONFIG_FILE); + properties.store(confFile); + }catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void processConfig(Path resource) throws IOException { + if (resource.getName(resource.getNameCount() - 1).toString().equals(CONFIG_FILE0)) { + // loads only enableOCR if is IPEDConfig.txt + UTF8Properties lproperties = new UTF8Properties(); + lproperties.load(resource.toFile()); + String value = lproperties.getProperty("enableOCR"); //$NON-NLS-1$ + if (value != null && !value.trim().isEmpty()) { + if (Boolean.valueOf(value.trim())) { + enableOCR = true; + } else { + enableOCR = false; + } + } else if (enableOCR == null) { + enableOCR = false; + } + } else { + super.processConfig(resource); + } + } + + @Override + public boolean isEnabled() { + return enableOCR; + } + + @Override + public void setEnabled(boolean enabled) { + enableOCR = enabled; + } + } diff --git a/iped-engine/src/main/java/iped/engine/config/ParsersConfig.java b/iped-engine/src/main/java/iped/engine/config/ParsersConfig.java index 7c5b34b333..d33345a6f2 100644 --- a/iped-engine/src/main/java/iped/engine/config/ParsersConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/ParsersConfig.java @@ -116,23 +116,23 @@ public String getConfiguration() { public void setConfiguration(String config) { parserConfigXml = config; } - + public String removeDisabledParsers(String parserConfigXml) { - String[] slices = parserConfigXml.split(PARSER_DISABLED_ATTR + "=\"true\""); - StringBuffer result = new StringBuffer(); + String[] slices = parserConfigXml.split(PARSER_DISABLED_ATTR+"=\"true\""); + StringBuffer result=new StringBuffer(); for (int i = 0; i < slices.length; i++) { String part = slices[i]; - if (i > 0) { + if(i>0) { int disabledParserEndIndex = part.indexOf(">"); - if (disabledParserEndIndex == 0 || part.charAt(disabledParserEndIndex - 1) != '/') { + if(disabledParserEndIndex==0 || part.charAt(disabledParserEndIndex-1)!='/') { disabledParserEndIndex = part.indexOf(""); } - part = part.substring(disabledParserEndIndex + 1); + part=part.substring(disabledParserEndIndex+1); } - if (i < slices.length - 1) { + if(i{ + public static final String PROFILE_EXTENSION = ".ipedprofile"; + private static ProfileManager singleton = null; + Set listOfProfileDirectories = new TreeSet(); + private File profilesDir; + private File confDir; + + + public static ProfileManager get() { + if(singleton==null) { + synchronized (ConfigurationManager.class) { + singleton = new ProfileManager(); + } + } + return singleton; + } + + /** + * populate the listOfProfileDirectories with all profiles located on iped/profile directory + */ + private ProfileManager() { + confDir = Paths.get(System.getProperty(IConfigurationDirectory.IPED_APP_ROOT), Configuration.CONF_DIR ).toFile(); + profilesDir = Paths.get(System.getProperty(IConfigurationDirectory.IPED_APP_ROOT), Configuration.PROFILES_DIR ).toFile(); + for(File currentProfile : profilesDir.listFiles() ){ + if(currentProfile.isDirectory()) { + ConfigurationDirectory currentProfileDirectory = new ConfigurationDirectory(confDir.toPath()); + currentProfileDirectory.addPath(currentProfile.toPath()); + currentProfileDirectory.setName(currentProfile.getName()); + listOfProfileDirectories.add(currentProfileDirectory); + }else { + if(currentProfile.getName().endsWith(PROFILE_EXTENSION)) { + SerializedConfigurationDirectory currentProfileDirectory = new SerializedConfigurationDirectory(currentProfile.toPath()); + currentProfileDirectory.setName(currentProfile.getName().substring(0,currentProfile.getName().lastIndexOf(PROFILE_EXTENSION))); + listOfProfileDirectories.add(currentProfileDirectory); + } + } + } + } + + public ConfigurationDirectory getDefaultProfile() { + confDir = Paths.get(System.getProperty(IConfigurationDirectory.IPED_APP_ROOT), Configuration.CONF_DIR ).toFile(); + ConfigurationDirectory currentProfileDirectory = new ConfigurationDirectory(confDir.toPath()); + currentProfileDirectory.setName("default"); + return currentProfileDirectory; + } + + @Override + public Set findObjects(Class clazz) { + return null; + } + + @Override + public Set findObjects(String className) { + return null; + } + + @Override + public Set getObjects() { + return listOfProfileDirectories; + } + + @Override + public void addObject(IConfigurationDirectory aObject) { + listOfProfileDirectories.add(aObject); + } + + @Override + public void removeObject(IConfigurationDirectory profileDirectory) { + File toDeleteProfile = new File(profilesDir, profileDirectory.getName()+PROFILE_EXTENSION); + if(toDeleteProfile.exists()) { + toDeleteProfile.delete(); + } + listOfProfileDirectories.remove(profileDirectory); + } + + public IConfigurationDirectory createProfilePath(String profileName, ConfigurationManager configurationManager) throws FileAlreadyExistsException { + File newProfile = new File(profilesDir, profileName); + if(newProfile.exists()) { + throw new FileAlreadyExistsException("Profile name already exists"); + } + + newProfile.mkdir(); + + Set> configs = configurationManager.getObjects(); + for (Iterator iterator = configs.iterator(); iterator.hasNext();) { + Configurable configurable = (Configurable) iterator.next(); + configurable.save(newProfile.toPath()); + } + + ConfigurationDirectory configDirectory = new ConfigurationDirectory(confDir.toPath()); + configDirectory.addPath(newProfile.toPath()); + configDirectory.setName(profileName); + listOfProfileDirectories.add(configDirectory); + + return configDirectory; + } + + public IConfigurationDirectory createProfile(String profileName, ConfigurationManager configurationManager) throws FileAlreadyExistsException { + File newProfile = new File(profilesDir, profileName + PROFILE_EXTENSION); + if(newProfile.exists()) { + throw new FileAlreadyExistsException("Profile name already exists"); + } + + try { + ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(newProfile)); + Set> configs = configurationManager.getObjects(); + for (Iterator iterator = configs.iterator(); iterator.hasNext();) { + Configurable configurable = (Configurable) iterator.next(); + oos.writeObject(configurable); + } + } catch (IOException e) { + e.printStackTrace(); + } + + + SerializedConfigurationDirectory configDirectory = new SerializedConfigurationDirectory(newProfile.toPath()); + configDirectory.setName(profileName); + listOfProfileDirectories.add(configDirectory); + + return configDirectory; + } +} diff --git a/iped-engine/src/main/java/iped/engine/config/RegexTaskConfig.java b/iped-engine/src/main/java/iped/engine/config/RegexTaskConfig.java index 1ce551840a..f115fb47e4 100644 --- a/iped-engine/src/main/java/iped/engine/config/RegexTaskConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/RegexTaskConfig.java @@ -1,13 +1,17 @@ package iped.engine.config; import java.io.Externalizable; +import java.io.File; import java.io.IOException; import java.io.InvalidClassException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.Serializable; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import org.apache.commons.lang3.tuple.Pair; @@ -49,6 +53,7 @@ public static class RegexEntry implements Serializable { private int prefix, suffix; private boolean ignoreCase; private String regex; + private String srcRegex; public String getRegexName() { return regexName; @@ -69,16 +74,17 @@ public boolean isIgnoreCase() { public String getRegex() { return regex; } - @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("regexName=").append(regexName).append(","); - sb.append("prefix=").append(prefix).append(","); - sb.append("suffix=").append(suffix).append(","); - sb.append("ignoreCase=").append(ignoreCase).append(","); - sb.append("regex=").append(regex); - return sb.toString(); + return regexName+","+ignoreCase+","+prefix+","+suffix+"="+srcRegex; + } + + public String getSrcRegex() { + return srcRegex; + } + + public void setSrcRegex(String srcRegex) { + this.srcRegex = srcRegex; } } @@ -151,6 +157,7 @@ public void processTaskConfig(Path resource) throws IOException { entry.ignoreCase = params.length > 1 ? Boolean.valueOf(params[1].trim()) : true; entry.prefix = params.length > 2 ? Integer.valueOf(params[2].trim()) : 0; entry.suffix = params.length > 3 ? Integer.valueOf(params[3].trim()) : 0; + entry.srcRegex = values[1].trim(); entry.regex = replace(values[1].trim()); replaceWordBoundaries(entry); regexList.add(entry); @@ -193,4 +200,25 @@ public void writeExternal(ObjectOutput out) throws IOException { } } + @Override + public void save(Path resource) { + try { + StringBuffer output = new StringBuffer(); + output.append(FORMAT_MATCHES+"="+formatRegexMatches); + output.append("\n"); + output.append("\n"); + for (Iterator iterator = regexList.iterator(); iterator.hasNext();) { + RegexEntry regexEntry = (RegexEntry) iterator.next(); + output.append(regexEntry.toString()); + output.append("\n"); + } + File confDir = new File(resource.toFile(), Configuration.CONF_DIR); + confDir.mkdirs(); + File confFile = new File(confDir, CONFIG_FILE); + + Files.write(confFile.toPath(),output.toString().getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + e.printStackTrace(); + } + } } diff --git a/iped-engine/src/main/java/iped/engine/config/SerializedConfigurationDirectory.java b/iped-engine/src/main/java/iped/engine/config/SerializedConfigurationDirectory.java new file mode 100644 index 0000000000..2cf69d64b4 --- /dev/null +++ b/iped-engine/src/main/java/iped/engine/config/SerializedConfigurationDirectory.java @@ -0,0 +1,65 @@ +package iped.engine.config; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.nio.file.Path; +import java.util.List; +import java.util.function.Predicate; + +import iped.configuration.Configurable; +import iped.configuration.IConfigurationDirectory; + +public class SerializedConfigurationDirectory implements IConfigurationDirectory, Comparable { + Path file=null; + String name; + + public SerializedConfigurationDirectory(Path file) { + this.file = file; + } + + @Override + public List getResourceLookupFolders() { + return null; + } + + @Override + public List lookUpResource(Predicate predicate) throws IOException { + // TODO Auto-generated method stub + return null; + } + + @Override + public List lookUpResource(Configurable configurable) throws IOException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String toString() { + return name; + } + + @Override + public int compareTo(IConfigurationDirectory o) { + return this.getName().compareTo(o.getName()); + } + + public ObjectInputStream openInputStream() throws IOException { + FileInputStream fi = new FileInputStream(file.toFile()); + return new ObjectInputStream(fi); + } + + @Override + public void addPath(Path path) { + // TODO Auto-generated method stub + } +} diff --git a/iped-engine/src/main/java/iped/engine/config/SignatureConfig.java b/iped-engine/src/main/java/iped/engine/config/SignatureConfig.java index 6c9c8d3c0a..9e7a2adf79 100644 --- a/iped-engine/src/main/java/iped/engine/config/SignatureConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/SignatureConfig.java @@ -57,4 +57,17 @@ public void processTaskConfig(Path resource) throws IOException { customSignaturesXml = new String(Files.readAllBytes(resource), StandardCharsets.UTF_8); } + @Override + public void save(Path resource) { + try { + File confDir = new File(resource.toFile(), Configuration.CONF_DIR); + confDir.mkdirs(); + File confFile = new File(confDir, CUSTOM_MIMES_CONFIG); + + Files.write(confFile.toPath(), customSignaturesXml.getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + e.printStackTrace(); + } + } + } diff --git a/iped-engine/src/main/java/iped/engine/config/SplashScreenConfig.java b/iped-engine/src/main/java/iped/engine/config/SplashScreenConfig.java index 5f56620cad..7222cabf90 100644 --- a/iped-engine/src/main/java/iped/engine/config/SplashScreenConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/SplashScreenConfig.java @@ -1,5 +1,6 @@ package iped.engine.config; +import java.io.File; import java.io.IOException; import java.nio.file.DirectoryStream.Filter; import java.nio.file.Path; @@ -9,7 +10,7 @@ public class SplashScreenConfig extends AbstractPropertiesConfigurable { private static final long serialVersionUID = 1L; - public static final String CONFIG_FILE = "conf/SplashScreenConfig.txt"; + public static final String CONFIG_FILE = "SplashScreenConfig.txt"; public static final String CUSTOM_MESSAGE = "customMessage"; private String message; @@ -36,4 +37,17 @@ public void processProperties(UTF8Properties properties) { message = value.trim(); } } + + @Override + public void save(Path resource) { + try { + File confDir = new File(resource.toFile(), Configuration.CONF_DIR); + confDir.mkdirs(); + File confFile = new File(confDir, CONFIG_FILE); + properties.store(confFile); + } catch (IOException e) { + e.printStackTrace(); + } + } + } diff --git a/iped-engine/src/main/java/iped/engine/config/SplitLargeBinaryConfig.java b/iped-engine/src/main/java/iped/engine/config/SplitLargeBinaryConfig.java index 0515e8a100..0588df699b 100644 --- a/iped-engine/src/main/java/iped/engine/config/SplitLargeBinaryConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/SplitLargeBinaryConfig.java @@ -1,5 +1,6 @@ package iped.engine.config; +import java.io.File; import java.io.IOException; import java.nio.file.DirectoryStream.Filter; import java.nio.file.Path; @@ -61,4 +62,16 @@ public boolean accept(Path entry) throws IOException { }; } + @Override + public void save(Path resource) { + try { + File confDir = new File(resource.toFile(), Configuration.CONF_DIR); + confDir.mkdirs(); + File confFile = new File(confDir, CONF_FILE); + properties.store(confFile); + } catch (Exception e) { + e.printStackTrace(); + } + } + } diff --git a/iped-engine/src/main/java/iped/engine/config/TaskInstallerConfig.java b/iped-engine/src/main/java/iped/engine/config/TaskInstallerConfig.java index 78f89ca3f7..8175d98c31 100644 --- a/iped-engine/src/main/java/iped/engine/config/TaskInstallerConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/TaskInstallerConfig.java @@ -8,6 +8,7 @@ import java.nio.file.DirectoryStream.Filter; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -24,18 +25,19 @@ import iped.configuration.Configurable; import iped.engine.task.AbstractTask; +import iped.engine.task.IScriptTask; import iped.engine.task.PythonTask; import iped.engine.task.ScriptTask; import iped.exception.IPEDException; public class TaskInstallerConfig implements Configurable { - /** * */ private static final long serialVersionUID = 1L; private static final String CONFIG_XML = "TaskInstaller.xml"; //$NON-NLS-1$ public static final String SCRIPT_BASE = "scripts/tasks"; //$NON-NLS-1$ + public static final String CUSTOM_SCRIPT_BASE = "scripts/tasks/custom"; //$NON-NLS-1$ private String xml; @@ -113,4 +115,49 @@ public void setConfiguration(String config) { this.xml = config; } + @Override + public void save(Path resource) { + try { + File confDir = new File(resource.toFile(), Configuration.CONF_DIR); + confDir.mkdirs(); + File confFile = new File(confDir, CONFIG_XML); + + Files.write(confFile.toPath(), xml.getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void update(List tasks) { + StringBuffer output=new StringBuffer(); + output.append(xml.substring(0,xml.indexOf(""))); + output.append("\n"); + for (Iterator iterator = tasks.iterator(); iterator.hasNext();) { + AbstractTask task = (AbstractTask) iterator.next(); + if(task instanceof IScriptTask) { + output.append("\n"); + }else { + output.append("\n"); + } + } + output.append(""); + xml = output.toString(); + } + + @Override + public void reset() { + // TODO Auto-generated method stub + } } diff --git a/iped-engine/src/main/java/iped/engine/core/Manager.java b/iped-engine/src/main/java/iped/engine/core/Manager.java index 05316c04be..f6cf9bc2ca 100644 --- a/iped-engine/src/main/java/iped/engine/core/Manager.java +++ b/iped-engine/src/main/java/iped/engine/core/Manager.java @@ -908,8 +908,13 @@ private void prepareOutputFolder() throws Exception { // copy non default profile File currentProfile = new File(Configuration.getInstance().configPath); if (!currentProfile.equals(defaultProfile)) { - IOUtil.copyDirectory(currentProfile, new File(output, Configuration.CASE_PROFILE_DIR), true); - resetLocalConfigToPortable(new File(output, Configuration.CASE_PROFILE_DIR + "/" + Configuration.LOCAL_CONFIG)); + if (currentProfile.isDirectory()) { + IOUtil.copyDirectory(currentProfile, new File(output, Configuration.CASE_PROFILE_DIR), true); + resetLocalConfigToPortable(new File(output, Configuration.CASE_PROFILE_DIR + "/" + Configuration.LOCAL_CONFIG)); + } else { + IOUtil.copyFile(currentProfile, new File(output, Configuration.CASE_PROFILE_DIR)); + // TODO we should also reset LocalConfig into profile file + } } File binDir = new File(Configuration.getInstance().appRoot, "bin"); //$NON-NLS-1$ diff --git a/iped-engine/src/main/java/iped/engine/data/IPEDSource.java b/iped-engine/src/main/java/iped/engine/data/IPEDSource.java index ed8ac42264..c128389101 100644 --- a/iped-engine/src/main/java/iped/engine/data/IPEDSource.java +++ b/iped-engine/src/main/java/iped/engine/data/IPEDSource.java @@ -365,7 +365,7 @@ private void loadLeafCategories() throws IOException { protected void loadCategoryTree() { CategoryConfig config = ConfigurationManager.get().findObject(CategoryConfig.class); - Category root = config.getRootCategory().clone(); + Category root = config.getRoot().clone(); // root.setName(rootName); ArrayList leafs = getLeafCategories(root); leafs.stream().forEach(l -> checkAndAddMissingCategory(root, l)); diff --git a/iped-engine/src/main/java/iped/engine/data/ReportInfo.java b/iped-engine/src/main/java/iped/engine/data/ReportInfo.java index e573a5f3d3..f7b09797b9 100644 --- a/iped-engine/src/main/java/iped/engine/data/ReportInfo.java +++ b/iped-engine/src/main/java/iped/engine/data/ReportInfo.java @@ -1,15 +1,8 @@ package iped.engine.data; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; +import java.io.*; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.ArrayList; import java.util.List; @@ -22,7 +15,7 @@ public class ReportInfo implements Serializable { /** - * + * */ private static final long serialVersionUID = 1L; @@ -44,12 +37,26 @@ public class ReportInfo implements Serializable { public List examinersID = new ArrayList<>(); public List evidences = new ArrayList<>(); public String finalEvidenceDesc; + public List investigatedName = new ArrayList<>(); + public String organizationName; + public String contact; + public String caseNotes; - class EvidenceDesc implements Serializable { + public class EvidenceDesc implements Serializable { private static final long serialVersionUID = 1L; String id, desc; + + public String getId() { + return id; + } + + public String getDesc() { + return desc; + } + + } /** @@ -149,6 +156,13 @@ public String getEvidenceDescHtml() { return mat.toString(); } + public EvidenceDesc getEvidenceDescInstance(String id, String desc){ + EvidenceDesc ed = new EvidenceDesc(); + ed.id = id; + ed.desc = desc; + return ed; + } + public String getExaminersText() { if (examiners.size() == 1) return examiners.get(0); @@ -158,6 +172,15 @@ public String getExaminersText() { return result; } + public String getInvestigatedNameText() { + if (investigatedName.size() == 1) + return investigatedName.get(0); + String result = ""; + for (String name : investigatedName) + result += name + "; "; + return result; + } + public void fillExaminersFromText(String text) { examiners.clear(); String[] es = text.split(";"); @@ -169,30 +192,77 @@ public void fillEvidenceFromText(String text) { finalEvidenceDesc = text; } + public void saveJsonInfoFile(File targetFile){ + try { + JSONObject reportInfoJson = new JSONObject(); + reportInfoJson.put("reportNumber", this.reportNumber ); + reportInfoJson.put("reportDate", this.reportDate); + reportInfoJson.put( "reportTitle", this.reportTitle ); + reportInfoJson.put( "examiners", this.examiners ); + reportInfoJson.put( "investigatedNames", this.investigatedName ); + reportInfoJson.put("organizationName", this.organizationName ); + reportInfoJson.put("contact", this.contact); + reportInfoJson.put("caseNotes", this.caseNotes); + reportInfoJson.put("caseNumber", this.caseNumber); + reportInfoJson.put("requestForm", this.requestForm); + reportInfoJson.put( "requestDate", this.requestDate ); + reportInfoJson.put("requester", this.requester); + reportInfoJson.put("labCaseNumber", this.labCaseNumber); + reportInfoJson.put("labCaseDate", this.labCaseDate); + JSONArray evidecesArray = new JSONArray(); + for( EvidenceDesc evidenceDesc : this.evidences ){ + JSONObject jo = new JSONObject(); + jo.put("id", evidenceDesc.id); + jo.put("desc", evidenceDesc.desc); + evidecesArray.put(jo); + } + reportInfoJson.put("evidences", evidecesArray ); + FileWriter writer = new FileWriter(targetFile, StandardCharsets.UTF_8); + writer.write(reportInfoJson.toString()); + writer.flush(); + writer.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + public void readJsonInfoFile(File file) throws IOException { finalEvidenceDesc = null; String str = new String(Files.readAllBytes(file.toPath()), "UTF-8"); JSONObject json = new JSONObject(str); - reportNumber = json.getString("reportNumber"); - reportDate = json.getString("reportDate"); - reportTitle = json.getString("reportTitle"); - JSONArray array = json.getJSONArray("examiners"); - for (int i = 0; i < array.length(); i++) - examiners.add(array.getString(i)); - caseNumber = json.getString("caseNumber"); - requestForm = json.getString("requestForm"); - requestDate = json.getString("requestDate"); - requester = json.getString("requester"); - labCaseNumber = json.getString("labCaseNumber"); - labCaseDate = json.getString("labCaseDate"); - array = json.getJSONArray("evidences"); - for (int i = 0; i < array.length(); i++) { - JSONObject evidence = array.getJSONObject(i); - EvidenceDesc e = new EvidenceDesc(); - e.id = evidence.getString("id"); - e.desc = evidence.getString("desc"); - evidences.add(e); + reportNumber = json.has("reportNumber") ? json.getString("reportNumber") : ""; + reportDate = json.has("reportDate") ? json.getString("reportDate") : ""; + reportTitle = json.has("reportTitle") ? json.getString("reportTitle") : ""; + JSONArray array = null; + if( json.has("examiners") ) { + array = json.getJSONArray("examiners"); + for (int i = 0; i < array.length(); i++) + examiners.add(array.getString(i)); + } + caseNumber = json.has("caseNumber") ? json.getString("caseNumber") : ""; + requestForm = json.has("requestForm") ? json.getString("requestForm") : ""; + requestDate = json.has("requestDate") ? json.getString("requestDate") : ""; + requester = json.has("requester") ? json.getString("requester") : ""; + labCaseNumber = json.has("labCaseNumber") ? json.getString("labCaseNumber") : ""; + labCaseDate = json.has("labCaseDate") ? json.getString("labCaseDate") : ""; + if( json.has("evidences") ) { + array = json.getJSONArray("evidences"); + for (int i = 0; i < array.length(); i++) { + JSONObject evidence = array.getJSONObject(i); + EvidenceDesc e = new EvidenceDesc(); + e.id = evidence.getString("id"); + e.desc = evidence.getString("desc"); + evidences.add(e); + } + } + if( json.has("investigatedNames") ) { + array = json.getJSONArray("investigatedNames"); + for (int i = 0; i < array.length(); i++) + investigatedName.add(array.getString(i)); } + organizationName = json.has("organizationName")? json.getString("organizationName") : ""; + contact = json.has("contact") ? json.getString("contact") : ""; + caseNotes = json.has("caseNotes") ? json.getString("caseNotes") : ""; } public File writeReportInfoFile() throws IOException { diff --git a/iped-engine/src/main/java/iped/engine/graph/GraphTask.java b/iped-engine/src/main/java/iped/engine/graph/GraphTask.java index 80e9802af4..7a5e28abaf 100644 --- a/iped-engine/src/main/java/iped/engine/graph/GraphTask.java +++ b/iped-engine/src/main/java/iped/engine/graph/GraphTask.java @@ -109,7 +109,11 @@ protected boolean removeEldestEntry(Entry> eldest) { @Override public List> getConfigurables() { - return Arrays.asList(new GraphTaskConfig()); + GraphTaskConfig result = ConfigurationManager.get().findObject(GraphTaskConfig.class); + if(result == null) { + result = new GraphTaskConfig(); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/graph/GraphTaskConfig.java b/iped-engine/src/main/java/iped/engine/graph/GraphTaskConfig.java index 5398292f7e..91ca4705b6 100644 --- a/iped-engine/src/main/java/iped/engine/graph/GraphTaskConfig.java +++ b/iped-engine/src/main/java/iped/engine/graph/GraphTaskConfig.java @@ -1,9 +1,13 @@ package iped.engine.graph; +import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.nio.file.Path; import iped.engine.config.AbstractTaskConfig; +import iped.engine.config.Configuration; public class GraphTaskConfig extends AbstractTaskConfig { @@ -17,6 +21,7 @@ public class GraphTaskConfig extends AbstractTaskConfig { public static final String CONFIG_FILE = "GraphConfig.json"; private GraphConfiguration graphConfig; + private String json; @Override public GraphConfiguration getConfiguration() { @@ -40,7 +45,20 @@ public String getTaskConfigFileName() { @Override public void processTaskConfig(Path resource) throws IOException { + json = Files.readString(resource); graphConfig = GraphConfiguration.loadFrom(resource.toFile()); } + @Override + public void save(Path resource) { + try { + File confDir = new File(resource.toFile(), Configuration.CONF_DIR); + confDir.mkdirs(); + File confFile = new File(confDir, CONFIG_FILE); + Files.write(confFile.toPath(),json.getBytes(StandardCharsets.UTF_8)); + }catch (Exception e) { + e.printStackTrace(); + } + } + } diff --git a/iped-engine/src/main/java/iped/engine/localization/Messages.java b/iped-engine/src/main/java/iped/engine/localization/Messages.java index 9eeb79e726..7b003119be 100644 --- a/iped-engine/src/main/java/iped/engine/localization/Messages.java +++ b/iped-engine/src/main/java/iped/engine/localization/Messages.java @@ -14,6 +14,8 @@ public class Messages { private static Logger LOGGER = LoggerFactory.getLogger(Messages.class); private static ResourceBundle RESOURCE_BUNDLE; + public static String TOOLTIP_SUFFIX=".tooltip"; + private Messages() { } @@ -38,4 +40,31 @@ public static String getString(String key) { throw e; } } + + public static String getString(String key, String defaultValue) { + if (RESOURCE_BUNDLE == null) { + String localeProp = System.getProperty(iped.localization.Messages.LOCALE_SYS_PROP); // $NON-NLS-1$ + Locale locale = localeProp != null ? Locale.forLanguageTag(localeProp) : Locale.getDefault(); + RESOURCE_BUNDLE = iped.localization.Messages.getExternalBundle(BUNDLE_NAME, locale); + String finalLocale = RESOURCE_BUNDLE.getLocale().toLanguageTag(); + if (finalLocale.equals("und")) //$NON-NLS-1$ + finalLocale = "en"; //$NON-NLS-1$ + if (!locale.toLanguageTag().equals(finalLocale)) + LOGGER.error("Bundle for Locale '" + locale.toLanguageTag() //$NON-NLS-1$ + + "' not found. Using bundle for " + finalLocale); //$NON-NLS-1$ + } + String result; + try { + result = RESOURCE_BUNDLE.getString(key); + + } catch (MissingResourceException e) { + result = defaultValue; + } + + //prepares html formating for tooltips if not already formated as such + if(key.endsWith(TOOLTIP_SUFFIX) && !result.startsWith("")) { + result = ""+result.replace("<", "<").replace(">", ">").replace("\n", "
")+""; + } + return result; + } } diff --git a/iped-engine/src/main/java/iped/engine/task/DocThumbTask.java b/iped-engine/src/main/java/iped/engine/task/DocThumbTask.java index bea7aca9d1..2d25762ef7 100644 --- a/iped-engine/src/main/java/iped/engine/task/DocThumbTask.java +++ b/iped-engine/src/main/java/iped/engine/task/DocThumbTask.java @@ -79,7 +79,11 @@ public class DocThumbTask extends ThumbTask { private boolean tempSet; public List> getConfigurables() { - return Arrays.asList(new DocThumbTaskConfig()); + DocThumbTaskConfig result = ConfigurationManager.get().findObject(DocThumbTaskConfig.class); + if(result == null) { + result = new DocThumbTaskConfig(); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/DuplicateTask.java b/iped-engine/src/main/java/iped/engine/task/DuplicateTask.java index c4c5fdcc0d..96af44b0de 100644 --- a/iped-engine/src/main/java/iped/engine/task/DuplicateTask.java +++ b/iped-engine/src/main/java/iped/engine/task/DuplicateTask.java @@ -40,7 +40,11 @@ public static boolean isIgnoreDuplicatesEnabled() { @Override public List> getConfigurables() { - return Arrays.asList(new EnableTaskProperty(ENABLE_PARAM)); + EnableTaskProperty result = ConfigurationManager.get().getEnableTaskPropertyObject(ENABLE_PARAM); + if(result == null) { + result = new EnableTaskProperty(ENABLE_PARAM); + } + return Arrays.asList(result); } public void process(IItem evidence) { diff --git a/iped-engine/src/main/java/iped/engine/task/EmbeddedDiskProcessTask.java b/iped-engine/src/main/java/iped/engine/task/EmbeddedDiskProcessTask.java index 19af1e7ef5..59bf593a0b 100644 --- a/iped-engine/src/main/java/iped/engine/task/EmbeddedDiskProcessTask.java +++ b/iped-engine/src/main/java/iped/engine/task/EmbeddedDiskProcessTask.java @@ -76,7 +76,11 @@ public boolean isEnabled() { @Override public List> getConfigurables() { - return Arrays.asList(new EnableTaskProperty(ENABLE_PARAM)); + EnableTaskProperty result = ConfigurationManager.get().getEnableTaskPropertyObject(ENABLE_PARAM); + if(result == null) { + result = new EnableTaskProperty(ENABLE_PARAM); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/EntropyTask.java b/iped-engine/src/main/java/iped/engine/task/EntropyTask.java index 2c71dc0b54..5afb2ff6ae 100644 --- a/iped-engine/src/main/java/iped/engine/task/EntropyTask.java +++ b/iped-engine/src/main/java/iped/engine/task/EntropyTask.java @@ -34,7 +34,11 @@ public void finish() throws Exception { @Override public List> getConfigurables() { - return Arrays.asList(new EnableTaskProperty(ENABLE_PARAM)); + EnableTaskProperty result = ConfigurationManager.get().getEnableTaskPropertyObject(ENABLE_PARAM); + if(result == null) { + result = new EnableTaskProperty(ENABLE_PARAM); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/ExportCSVTask.java b/iped-engine/src/main/java/iped/engine/task/ExportCSVTask.java index 647a655c8c..69acedb636 100644 --- a/iped-engine/src/main/java/iped/engine/task/ExportCSVTask.java +++ b/iped-engine/src/main/java/iped/engine/task/ExportCSVTask.java @@ -319,7 +319,11 @@ public void finish() throws IOException { @Override public List> getConfigurables() { - return Arrays.asList(new EnableTaskProperty(ENABLE_PARAM)); + EnableTaskProperty result = ConfigurationManager.get().getEnableTaskPropertyObject(ENABLE_PARAM); + if(result == null) { + result = new EnableTaskProperty(ENABLE_PARAM); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/ExportFileTask.java b/iped-engine/src/main/java/iped/engine/task/ExportFileTask.java index f2b75327c7..5fedeaa157 100644 --- a/iped-engine/src/main/java/iped/engine/task/ExportFileTask.java +++ b/iped-engine/src/main/java/iped/engine/task/ExportFileTask.java @@ -709,8 +709,19 @@ public SeekableInputStream getSeekableInputStream(String identifier) throws IOEx @Override public List> getConfigurables() { - return Arrays.asList(new EnableTaskProperty(ENABLE_PARAM), new ExportByCategoriesConfig(), - new ExportByKeywordsConfig()); + EnableTaskProperty result = ConfigurationManager.get().getEnableTaskPropertyObject(ENABLE_PARAM); + if(result == null) { + result = new EnableTaskProperty(ENABLE_PARAM); + } + ExportByCategoriesConfig result2 = ConfigurationManager.get().findObject(ExportByCategoriesConfig.class); + if(result2 == null) { + result2 = new ExportByCategoriesConfig(); + } + ExportByKeywordsConfig result3 = ConfigurationManager.get().findObject(ExportByKeywordsConfig.class); + if(result3 == null) { + result3 = new ExportByKeywordsConfig(); + } + return Arrays.asList(result, result2, result3); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/FragmentLargeBinaryTask.java b/iped-engine/src/main/java/iped/engine/task/FragmentLargeBinaryTask.java index 3fb6f9d073..bb1ca7d213 100644 --- a/iped-engine/src/main/java/iped/engine/task/FragmentLargeBinaryTask.java +++ b/iped-engine/src/main/java/iped/engine/task/FragmentLargeBinaryTask.java @@ -30,7 +30,11 @@ public class FragmentLargeBinaryTask extends BaseCarveTask { @Override public List> getConfigurables() { - return Arrays.asList(new SplitLargeBinaryConfig()); + SplitLargeBinaryConfig result = ConfigurationManager.get().findObject(SplitLargeBinaryConfig.class); + if(result == null) { + result = new SplitLargeBinaryConfig(); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/HTMLReportTask.java b/iped-engine/src/main/java/iped/engine/task/HTMLReportTask.java index bb565b8a26..2c33c8aaeb 100644 --- a/iped-engine/src/main/java/iped/engine/task/HTMLReportTask.java +++ b/iped-engine/src/main/java/iped/engine/task/HTMLReportTask.java @@ -197,7 +197,11 @@ public boolean isEnabled() { } public List> getConfigurables() { - return Arrays.asList(new HtmlReportTaskConfig()); + HtmlReportTaskConfig result = ConfigurationManager.get().findObject(HtmlReportTaskConfig.class); + if(result == null) { + result = new HtmlReportTaskConfig(); + } + return Arrays.asList(result); } /** diff --git a/iped-engine/src/main/java/iped/engine/task/HashDBLookupTask.java b/iped-engine/src/main/java/iped/engine/task/HashDBLookupTask.java index 0de6cd3c47..d607bd6e91 100644 --- a/iped-engine/src/main/java/iped/engine/task/HashDBLookupTask.java +++ b/iped-engine/src/main/java/iped/engine/task/HashDBLookupTask.java @@ -65,7 +65,11 @@ public class HashDBLookupTask extends AbstractTask { @Override public List> getConfigurables() { - return Arrays.asList(new HashDBLookupConfig()); + HashDBLookupConfig result = ConfigurationManager.get().findObject(HashDBLookupConfig.class); + if(result == null) { + result = new HashDBLookupConfig(); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/HashTask.java b/iped-engine/src/main/java/iped/engine/task/HashTask.java index d3f5b59a64..0cbfafc911 100644 --- a/iped-engine/src/main/java/iped/engine/task/HashTask.java +++ b/iped-engine/src/main/java/iped/engine/task/HashTask.java @@ -81,7 +81,11 @@ public boolean isEnabled() { @Override public List> getConfigurables() { - return Arrays.asList(new HashTaskConfig()); + HashTaskConfig result = ConfigurationManager.get().findObject(HashTaskConfig.class); + if(result == null) { + result = new HashTaskConfig(); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/IScriptTask.java b/iped-engine/src/main/java/iped/engine/task/IScriptTask.java new file mode 100644 index 0000000000..7b3aef53b4 --- /dev/null +++ b/iped-engine/src/main/java/iped/engine/task/IScriptTask.java @@ -0,0 +1,13 @@ +package iped.engine.task; + +public interface IScriptTask { + public String getScriptFileName(); + + /** + * Basic validation to the script. + * + * @return suggested class to position this task before in execution pipeline + * @throws ScriptTaskComplianceException + */ + Class checkTaskCompliance(String src) throws ScriptTaskComplianceException; +} diff --git a/iped-engine/src/main/java/iped/engine/task/ImageThumbTask.java b/iped-engine/src/main/java/iped/engine/task/ImageThumbTask.java index bef7b14b79..4528355944 100644 --- a/iped-engine/src/main/java/iped/engine/task/ImageThumbTask.java +++ b/iped-engine/src/main/java/iped/engine/task/ImageThumbTask.java @@ -64,7 +64,11 @@ public ImageThumbTaskConfig getImageThumbConfig() { } public List> getConfigurables() { - return Arrays.asList(new ImageThumbTaskConfig()); + ImageThumbTaskConfig result = ConfigurationManager.get().findObject(ImageThumbTaskConfig.class); + if(result == null) { + result = new ImageThumbTaskConfig(); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/LanguageDetectTask.java b/iped-engine/src/main/java/iped/engine/task/LanguageDetectTask.java index 4b6217d364..156c824c4d 100644 --- a/iped-engine/src/main/java/iped/engine/task/LanguageDetectTask.java +++ b/iped-engine/src/main/java/iped/engine/task/LanguageDetectTask.java @@ -51,7 +51,11 @@ public boolean isEnabled() { @Override public List> getConfigurables() { - return Arrays.asList(new EnableTaskProperty(ENABLE_PARAM)); + EnableTaskProperty result = ConfigurationManager.get().getEnableTaskPropertyObject(ENABLE_PARAM); + if(result == null) { + result = new EnableTaskProperty(ENABLE_PARAM); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/MakePreviewTask.java b/iped-engine/src/main/java/iped/engine/task/MakePreviewTask.java index dd1fd22fa3..79f6214d91 100644 --- a/iped-engine/src/main/java/iped/engine/task/MakePreviewTask.java +++ b/iped-engine/src/main/java/iped/engine/task/MakePreviewTask.java @@ -53,7 +53,11 @@ public class MakePreviewTask extends AbstractTask { private volatile Throwable exception; public List> getConfigurables() { - return Arrays.asList(new MakePreviewConfig()); + MakePreviewConfig result = ConfigurationManager.get().findObject(MakePreviewConfig.class); + if(result == null) { + result = new MakePreviewConfig(); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/MinIOTask.java b/iped-engine/src/main/java/iped/engine/task/MinIOTask.java index 3c2d3f28f7..171596dfc5 100644 --- a/iped-engine/src/main/java/iped/engine/task/MinIOTask.java +++ b/iped-engine/src/main/java/iped/engine/task/MinIOTask.java @@ -198,7 +198,11 @@ public boolean isEnabled() { } public List> getConfigurables() { - return Arrays.asList(new MinIOConfig()); + MinIOConfig result = ConfigurationManager.get().findObject(MinIOConfig.class); + if(result == null) { + result = new MinIOConfig(); + } + return Arrays.asList(result); } public static boolean isTaskEnabled() { diff --git a/iped-engine/src/main/java/iped/engine/task/NamedEntityTask.java b/iped-engine/src/main/java/iped/engine/task/NamedEntityTask.java index 58cb210a24..217e6a94ad 100644 --- a/iped-engine/src/main/java/iped/engine/task/NamedEntityTask.java +++ b/iped-engine/src/main/java/iped/engine/task/NamedEntityTask.java @@ -53,7 +53,11 @@ public boolean isEnabled() { } public List> getConfigurables() { - return Arrays.asList(new NamedEntityTaskConfig()); + NamedEntityTaskConfig result = ConfigurationManager.get().findObject(NamedEntityTaskConfig.class); + if(result == null) { + result = new NamedEntityTaskConfig(); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/ParsingTask.java b/iped-engine/src/main/java/iped/engine/task/ParsingTask.java index e149f5d0b2..c382a25105 100644 --- a/iped-engine/src/main/java/iped/engine/task/ParsingTask.java +++ b/iped-engine/src/main/java/iped/engine/task/ParsingTask.java @@ -768,8 +768,27 @@ private static void removeMetadataAndDuplicates(Metadata metadata, Property prop } public List> getConfigurables() { - return Arrays.asList(new ParsingTaskConfig(), new CategoryToExpandConfig(), new OCRConfig(), - new ParsersConfig(), new ExternalParsersConfig()); + ParsingTaskConfig result = ConfigurationManager.get().findObject(ParsingTaskConfig.class); + if(result == null) { + result = new ParsingTaskConfig(); + } + CategoryToExpandConfig result1 = ConfigurationManager.get().findObject(CategoryToExpandConfig.class); + if(result1 == null) { + result1 = new CategoryToExpandConfig(); + } + OCRConfig result2 = ConfigurationManager.get().findObject(OCRConfig.class); + if(result2 == null) { + result2 = new OCRConfig(); + } + ParsersConfig result3 = ConfigurationManager.get().findObject(ParsersConfig.class); + if(result3 == null) { + result3 = new ParsersConfig(); + } + ExternalParsersConfig result4 = ConfigurationManager.get().findObject(ExternalParsersConfig.class); + if(result4 == null) { + result4 = new ExternalParsersConfig(); + } + return Arrays.asList(result,result1,result2,result3,result4); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/PhotoDNALookup.java b/iped-engine/src/main/java/iped/engine/task/PhotoDNALookup.java index 50ac6b4617..42d5e5db87 100644 --- a/iped-engine/src/main/java/iped/engine/task/PhotoDNALookup.java +++ b/iped-engine/src/main/java/iped/engine/task/PhotoDNALookup.java @@ -65,7 +65,11 @@ public class PhotoDNALookup extends AbstractTask { @Override public List> getConfigurables() { - return Arrays.asList(new PhotoDNALookupConfig()); + PhotoDNALookupConfig result = ConfigurationManager.get().findObject(PhotoDNALookupConfig.class); + if(result == null) { + result = new PhotoDNALookupConfig(); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/PhotoDNATask.java b/iped-engine/src/main/java/iped/engine/task/PhotoDNATask.java index 5ead7574ea..5c1ea75f78 100644 --- a/iped-engine/src/main/java/iped/engine/task/PhotoDNATask.java +++ b/iped-engine/src/main/java/iped/engine/task/PhotoDNATask.java @@ -33,7 +33,11 @@ public class PhotoDNATask extends AbstractTask { private PhotoDNA photodna; public List> getConfigurables() { - return Arrays.asList(new PhotoDNAConfig()); + PhotoDNAConfig result = ConfigurationManager.get().findObject(PhotoDNAConfig.class); + if(result == null) { + result = new PhotoDNAConfig(); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/PythonTask.java b/iped-engine/src/main/java/iped/engine/task/PythonTask.java index 9ecae6aa74..0d831f1d91 100644 --- a/iped-engine/src/main/java/iped/engine/task/PythonTask.java +++ b/iped-engine/src/main/java/iped/engine/task/PythonTask.java @@ -1,6 +1,9 @@ package iped.engine.task; +import java.io.BufferedReader; import java.io.File; +import java.io.IOException; +import java.io.StringReader; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -23,7 +26,7 @@ import jep.JepException; import jep.NDArray; -public class PythonTask extends AbstractTask { +public class PythonTask extends AbstractTask implements IScriptTask { private static final String JEP_NOT_FOUND = PythonParser.JEP_NOT_FOUND; private static final String DISABLED = PythonParser.DISABLED; @@ -45,6 +48,7 @@ public class PythonTask extends AbstractTask { private boolean isEnabled = true; private boolean sendToNextTaskExists = true; private boolean throwExceptionInsteadOfLogging = false; + private List> configurables; public PythonTask(File scriptFile) { this.scriptFile = scriptFile; @@ -198,7 +202,7 @@ private String getInstanceMethod(String function) { public String getName() { return scriptFile.getName(); } - + @Override public List> getConfigurables() { try { @@ -206,8 +210,27 @@ public List> getConfigurables() { List> configs = null; if (j != null) { configs = (List>) j.invoke(getInstanceMethod("getConfigurables")); + Configurable[] configsArray = configs.toArray(new Configurable[0]); + for (int i = 0; i < configsArray.length; i++) { + Configurable configurable = configsArray[i]; + Configurable currentConfig = ConfigurationManager.get() + .findObject((Class>) configurable.getClass()); + if (currentConfig == null) { + try { + configurable.reset(); + ConfigurationManager.get().loadConfig(configurable, true); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } else { + configs.remove(configurable); + configs.add(currentConfig); + } + } } - return configs != null ? configs : Collections.emptyList(); + configurables = configs != null ? configs : Collections.emptyList(); + return configurables; } catch (JepException e) { throw new RuntimeException(e); @@ -322,4 +345,63 @@ public void process(IItem item) throws Exception { } } + @Override + public String getScriptFileName() { + return scriptFile.getAbsolutePath(); + } + + @Override + public Class checkTaskCompliance(String src) throws ScriptTaskComplianceException { + try { + BufferedReader in = new BufferedReader(new StringReader(src)); //$NON-NLS-1$ + String str = null; + boolean processMethodFound=false; + boolean initMethodFound=false; + boolean isEnabledMethodFound=false; + boolean getConfigurablesMethodFound=false; + while ((str = in.readLine()) != null) { + str=str.trim(); + if (str.startsWith("class ")) { + String className = str.substring(6, str.indexOf(":")); + if (!this.getName().startsWith(className)) { + throw new ScriptTaskComplianceException("Class name differs from file name."); + } + } + if(str.startsWith("def")) { + str=str.substring(3).trim(); + if(str.startsWith("process")) { + processMethodFound=true; + } + if(str.startsWith("isEnabled")) { + isEnabledMethodFound=true; + } + if(str.startsWith("init")) { + initMethodFound=true; + } + if(str.startsWith("getConfigurables")) { + getConfigurablesMethodFound=true; + } + } + if(processMethodFound && initMethodFound && isEnabledMethodFound && getConfigurablesMethodFound) break; + } + in.close(); + if(!processMethodFound) { + throw new ScriptTaskComplianceException("No 'process' method implementation found on script."); + } + if(!initMethodFound) { + throw new ScriptTaskComplianceException("No 'init' method implementation found on script."); + } + if(!isEnabledMethodFound) { + throw new ScriptTaskComplianceException("No 'isEnabled' method implementation found on script."); + } + if(!getConfigurablesMethodFound) { + throw new ScriptTaskComplianceException("No 'getConfigurables' method implementation found on script."); + } + in.close(); + }catch(Exception e) { + throw new ScriptTaskComplianceException(e); + } + return null; + } + } diff --git a/iped-engine/src/main/java/iped/engine/task/QRCodeTask.java b/iped-engine/src/main/java/iped/engine/task/QRCodeTask.java index e9ed37e26c..65442c43c2 100644 --- a/iped-engine/src/main/java/iped/engine/task/QRCodeTask.java +++ b/iped-engine/src/main/java/iped/engine/task/QRCodeTask.java @@ -70,7 +70,11 @@ public static void setEnabled(boolean enabled) { @Override public List> getConfigurables() { - return Arrays.asList(new EnableTaskProperty(ENABLE_PARAM)); + EnableTaskProperty result = ConfigurationManager.get().getEnableTaskPropertyObject(ENABLE_PARAM); + if(result == null) { + result = new EnableTaskProperty(ENABLE_PARAM); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/ScriptTask.java b/iped-engine/src/main/java/iped/engine/task/ScriptTask.java index dcced4e9d4..96c55bb2b6 100644 --- a/iped-engine/src/main/java/iped/engine/task/ScriptTask.java +++ b/iped-engine/src/main/java/iped/engine/task/ScriptTask.java @@ -22,6 +22,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; +import java.io.StringReader; import java.io.UnsupportedEncodingException; import java.util.Collections; import java.util.List; @@ -39,7 +40,7 @@ import iped.engine.data.IPEDSource; import iped.engine.search.IPEDSearcher; -public class ScriptTask extends AbstractTask { +public class ScriptTask extends AbstractTask implements IScriptTask { private static IPEDSource ipedCase; private static int numInstances = 0; @@ -59,20 +60,19 @@ public ScriptTask(File scriptFile) { } } - public void loadScript(File file) - throws IOException, ScriptException, UnsupportedEncodingException, NoSuchMethodException { - + public void loadScript(File file) throws IOException, ScriptException, UnsupportedEncodingException, NoSuchMethodException { try (InputStreamReader reader = new InputStreamReader(new FileInputStream(file), "UTF-8")) { //$NON-NLS-1$ - ScriptEngineManager manager = new ScriptEngineManager(); - String ext = file.getName().substring(file.getName().lastIndexOf('.') + 1); - engine = manager.getEngineByExtension(ext); - Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE); - // bindings.put("polyglot.js.nashorn-compat", true); - engine.eval(reader); - inv = (Invocable) engine; + String ext = file.getName().substring(file.getName().lastIndexOf('.') + 1); // $NON-NLS-1$ + engine = manager.getEngineByExtension(ext); // $NON-NLS-1$ + if(engine==null) { + throw new ScriptException("No engine configured for this file type."); + }else { + Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE); + engine.eval(reader); + inv = (Invocable) engine; + } } - } @Override @@ -130,7 +130,49 @@ public void process(IItem e) throws Exception { @Override public String getName() { + if (scriptName == null) { + try { + scriptName = (String) inv.invokeFunction("getName"); + } catch (Exception e) { + scriptName = scriptFile.getName(); + } + } return scriptName; } + @Override + public String getScriptFileName() { + return scriptFile.getAbsolutePath(); + } + + /** + * Stub interface to validate script code + * @author patrick.pdb + * + */ + public interface ITask{ + public abstract List> getConfigurables(); + public abstract void init(ConfigurationManager configurationManager) throws Exception; + abstract public void finish() throws Exception; + abstract public void process(IItem evidence) throws Exception; + } + + @Override + public Class checkTaskCompliance(String src) throws ScriptTaskComplianceException { + ITask task = null; + try { + ScriptEngineManager manager = new ScriptEngineManager(); + engine = manager.getEngineByExtension("js"); // $NON-NLS-1$ + engine.eval(new StringReader(src)); + inv = (Invocable) engine; + task = inv.getInterface(ITask.class); + }catch (Exception e) { + throw new ScriptTaskComplianceException(e); + } + if(task==null) { + throw new ScriptTaskComplianceException("Not all methods implementations found. Required methods are: getConfigurables, init, finish and process."); + } + return null; + } + } diff --git a/iped-engine/src/main/java/iped/engine/task/ScriptTaskComplianceException.java b/iped-engine/src/main/java/iped/engine/task/ScriptTaskComplianceException.java new file mode 100644 index 0000000000..ac30c6a4d7 --- /dev/null +++ b/iped-engine/src/main/java/iped/engine/task/ScriptTaskComplianceException.java @@ -0,0 +1,12 @@ +package iped.engine.task; + +public class ScriptTaskComplianceException extends Exception { + public ScriptTaskComplianceException(Exception e) { + super(e); + } + + public ScriptTaskComplianceException(String string) { + super(string); + } + +} diff --git a/iped-engine/src/main/java/iped/engine/task/SetCategoryTask.java b/iped-engine/src/main/java/iped/engine/task/SetCategoryTask.java index eadf3c7b67..3b34e3b6bb 100644 --- a/iped-engine/src/main/java/iped/engine/task/SetCategoryTask.java +++ b/iped-engine/src/main/java/iped/engine/task/SetCategoryTask.java @@ -40,7 +40,11 @@ public class SetCategoryTask extends AbstractTask { @Override public List> getConfigurables() { - return Arrays.asList(new CategoryConfig()); + CategoryConfig result = ConfigurationManager.get().findObject(CategoryConfig.class); + if(result == null) { + result = new CategoryConfig(); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/SignatureTask.java b/iped-engine/src/main/java/iped/engine/task/SignatureTask.java index d6499f2e2e..e2e20184a4 100644 --- a/iped-engine/src/main/java/iped/engine/task/SignatureTask.java +++ b/iped-engine/src/main/java/iped/engine/task/SignatureTask.java @@ -141,7 +141,11 @@ private boolean hasVHDFooter(IItem item) { @Override public List> getConfigurables() { - return Arrays.asList(new SignatureConfig()); + SignatureConfig result = ConfigurationManager.get().findObject(SignatureConfig.class); + if(result == null) { + result = new SignatureConfig(); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/TempFileTask.java b/iped-engine/src/main/java/iped/engine/task/TempFileTask.java index 9225b46359..4a9a409f0f 100644 --- a/iped-engine/src/main/java/iped/engine/task/TempFileTask.java +++ b/iped-engine/src/main/java/iped/engine/task/TempFileTask.java @@ -40,7 +40,11 @@ public boolean isEnabled() { @Override public List> getConfigurables() { - return Arrays.asList(new TempFileTaskConfig()); + TempFileTaskConfig result = ConfigurationManager.get().findObject(TempFileTaskConfig.class); + if (result == null) { + result = new TempFileTaskConfig(); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/carver/CarverTask.java b/iped-engine/src/main/java/iped/engine/task/carver/CarverTask.java index 8dc38ffb16..5ab5d15dc8 100644 --- a/iped-engine/src/main/java/iped/engine/task/carver/CarverTask.java +++ b/iped-engine/src/main/java/iped/engine/task/carver/CarverTask.java @@ -211,7 +211,11 @@ private Hit findSig(InputStream in) throws Exception { @Override public List> getConfigurables() { - return Arrays.asList(new CarverTaskConfig()); + CarverTaskConfig result = ConfigurationManager.get().findObject(CarverTaskConfig.class); + if(result == null) { + result = new CarverTaskConfig(); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/carver/CarverTaskConfig.java b/iped-engine/src/main/java/iped/engine/task/carver/CarverTaskConfig.java index 465b30f89f..01e4435e4f 100644 --- a/iped-engine/src/main/java/iped/engine/task/carver/CarverTaskConfig.java +++ b/iped-engine/src/main/java/iped/engine/task/carver/CarverTaskConfig.java @@ -1,7 +1,10 @@ package iped.engine.task.carver; +import java.io.File; import java.io.IOException; import java.nio.file.DirectoryStream.Filter; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.nio.file.Path; import iped.engine.config.AbstractTaskConfig; @@ -66,4 +69,24 @@ public void processTaskConfig(Path resource) throws IOException { } + @Override + public void save(Path resource) { + try { + String output = carverConfiguration.getXMLString(); + if(output!=null) { + File confDir = new File(resource.toFile(), Configuration.CONF_DIR); + confDir.mkdirs(); + File confFile = new File(confDir, GLOBAL_CARVER_CONFIG); + Files.write(confFile.toPath(),output.toString().getBytes(StandardCharsets.UTF_8)); + } + }catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void reset() { + carverConfiguration.reset(); + } + } diff --git a/iped-engine/src/main/java/iped/engine/task/carver/KnownMetCarveTask.java b/iped-engine/src/main/java/iped/engine/task/carver/KnownMetCarveTask.java index f4b8eec521..8bd1d5b721 100644 --- a/iped-engine/src/main/java/iped/engine/task/carver/KnownMetCarveTask.java +++ b/iped-engine/src/main/java/iped/engine/task/carver/KnownMetCarveTask.java @@ -104,7 +104,11 @@ public boolean isEnabled() { @Override public List> getConfigurables() { - return Arrays.asList(new EnableTaskProperty(ENABLE_PARAM)); + EnableTaskProperty result = ConfigurationManager.get().getEnableTaskPropertyObject(ENABLE_PARAM); + if(result == null) { + result = new EnableTaskProperty(ENABLE_PARAM); + } + return Arrays.asList(result); } /** diff --git a/iped-engine/src/main/java/iped/engine/task/carver/LedCarveTask.java b/iped-engine/src/main/java/iped/engine/task/carver/LedCarveTask.java index ae0d208292..d26ba8c35a 100644 --- a/iped-engine/src/main/java/iped/engine/task/carver/LedCarveTask.java +++ b/iped-engine/src/main/java/iped/engine/task/carver/LedCarveTask.java @@ -100,7 +100,11 @@ public static void setEnabled(boolean enabled) { @Override public List> getConfigurables() { - return Arrays.asList(new EnableTaskProperty(ENABLE_PARAM)); + EnableTaskProperty result = ConfigurationManager.get().getEnableTaskPropertyObject(ENABLE_PARAM); + if(result == null) { + result = new EnableTaskProperty(ENABLE_PARAM); + } + return Arrays.asList(result); } /** diff --git a/iped-engine/src/main/java/iped/engine/task/carver/XMLCarverConfiguration.java b/iped-engine/src/main/java/iped/engine/task/carver/XMLCarverConfiguration.java index e6a5d0f348..b78e05ddd0 100644 --- a/iped-engine/src/main/java/iped/engine/task/carver/XMLCarverConfiguration.java +++ b/iped-engine/src/main/java/iped/engine/task/carver/XMLCarverConfiguration.java @@ -1,21 +1,39 @@ package iped.engine.task.carver; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.Serializable; +import java.net.URL; import java.nio.file.Files; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; import org.apache.tika.mime.MediaType; import org.arabidopsis.ahocorasick.AhoCorasick; import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; import iped.carvers.api.CarvedItemListener; import iped.carvers.api.Carver; @@ -36,23 +54,78 @@ public class XMLCarverConfiguration implements CarverConfiguration, Serializable private static AhoCorasick tree = null; private static String CARVE_DIR_INDIVIDUAIS = "carvers"; + Document mergedDoc = null; private ArrayList originalXmls = new ArrayList<>(); private boolean ignoreCorrupted = true; - protected HashSet TYPES_TO_PROCESS; + protected HashSet TYPES_TO_PROCESS= new HashSet(); protected HashSet TYPES_TO_NOT_PROCESS = new HashSet(); protected HashSet TYPES_TO_CARVE = new HashSet(); - private ArrayList carverTypesArray = new ArrayList(); + private ArrayList enabledCarverTypes = new ArrayList(); + + private ArrayList availableCarverTypes = new ArrayList(); + private int idseq = 0; + + public static URL xsdFile=null; + + static { + try { + xsdFile = XMLCarverConfiguration.class.getResource("CarverConfig.xsd"); + }catch(Exception e) { + System.out.println("Warning: CarverConfig XSD file not loaded."); + } + } + + public DocumentBuilder getDocBuilder() throws SAXException, ParserConfigurationException { + SchemaFactory factory = + SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = factory.newSchema(xsdFile); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setSchema(schema); + dbf.setNamespaceAware(true); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + docBuilder.setErrorHandler(new ErrorHandler() { + @Override + public void warning(SAXParseException exception) throws SAXException { + } + + @Override + public void fatalError(SAXParseException exception) throws SAXException { + } + + @Override + public void error(SAXParseException exception) throws SAXException { + throw exception; + } + }); + return docBuilder; + } + public void loadXMLConfigFile(File confFile) throws IOException { - originalXmls.add(Files.readString(confFile.toPath())); - Document doc = null; try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(false); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = getDocBuilder().parse(confFile); + loadConfigDocument(doc); + //adds the file if it was parsed successfully + originalXmls.add(Files.readString(confFile.toPath())); + }catch (SAXException | ParserConfigurationException e) { + throw new IOException(e); + } + } - doc = docBuilder.parse(confFile); + public void loadXMLConfigFile(String xml) throws IOException, SAXException, ParserConfigurationException { + ByteArrayInputStream bis = new ByteArrayInputStream(xml.getBytes()); + Document doc = getDocBuilder().parse(bis); + reset(); + loadConfigDocument(doc); + } + + public void loadConfigDocument(Document docParam) throws IOException { + try { + Document doc = docParam; + if(mergedDoc==null) { + mergedDoc = doc; + } Element root = doc.getDocumentElement(); @@ -60,14 +133,15 @@ public void loadXMLConfigFile(File confFile) throws IOException { for (int i = 0; i < toProcessEls.getLength(); i++) { Element toProcessEl = (Element) toProcessEls.item(i); - if (TYPES_TO_PROCESS == null) { - TYPES_TO_PROCESS = new HashSet(); - } String line = toProcessEl.getTextContent().trim(); String[] types = line.split(";"); //$NON-NLS-1$ //$NON-NLS-2$ for (String type : types) { TYPES_TO_PROCESS.add(MediaType.parse(type.trim())); } + if(mergedDoc!=doc) { + Node imported = mergedDoc.importNode(toProcessEl, true); + mergedDoc.getDocumentElement().appendChild(imported); + } } NodeList toNotProcessEls = root.getElementsByTagName("typesToNotProcess"); @@ -82,18 +156,37 @@ public void loadXMLConfigFile(File confFile) throws IOException { for (String type : types) { TYPES_TO_NOT_PROCESS.add(type.trim()); } + if(mergedDoc!=doc) { + Node imported = mergedDoc.importNode(toNotProcessEl, true); + mergedDoc.getDocumentElement().appendChild(imported); + } } NodeList ignoreCorruptedEls = root.getElementsByTagName("ignoreCorrupted"); ignoreCorrupted = Boolean.valueOf(ignoreCorruptedEls.item(0).getTextContent().trim()); + if(mergedDoc!=doc) { + NodeList mergedIgnoreCorruptedEls = mergedDoc.getDocumentElement().getElementsByTagName("ignoreCorrupted"); + if(mergedIgnoreCorruptedEls!=null) { + mergedIgnoreCorruptedEls.item(0).setTextContent(ignoreCorruptedEls.item(0).getTextContent().trim()); + }else { + Node imported = mergedDoc.importNode(ignoreCorruptedEls.item(0), true); + mergedDoc.getDocumentElement().appendChild(imported); + } + } NodeList carversEls = root.getElementsByTagName("carverTypes"); for (int i = 0; i < carversEls.getLength(); i++) { Element carverEls = (Element) carversEls.item(i); + + if(mergedDoc!=doc) { + Node imported = mergedDoc.importNode(carverEls, true); + mergedDoc.getDocumentElement().appendChild(imported); + } + NodeList carverTypeEls = carverEls.getElementsByTagName("carverType"); for (int j = 0; j < carverTypeEls.getLength(); j++) { Element carverTypeEl = (Element) carverTypeEls.item(j); - + Element carverClass = XMLUtil.getFirstElement(carverTypeEl, "carverClass"); Element sigsEl = XMLUtil.getFirstElement(carverTypeEl, "signatures"); @@ -137,14 +230,35 @@ public void loadXMLConfigFile(File confFile) throws IOException { } } TYPES_TO_CARVE.add(ct.getMimeType()); - carverTypesArray.add(ct); + if("false".equals(carverTypeEl.getAttribute("enabled"))) { + ct.setEnabled(false); + }else { + enabledCarverTypes.add(ct); + ct.setEnabled(true); + } + ct.id = idseq++; + availableCarverTypes.add(ct); } else { Class classe = this.getClass().getClassLoader().loadClass(carverClass.getTextContent()); Carver cv = (Carver) classe.getDeclaredConstructor().newInstance(); CarverType[] cts = cv.getCarverTypes(); + boolean ctEnabled; + int ctid = idseq++; + if("false".equals(carverTypeEl.getAttribute("enabled"))) { + ctEnabled=false; + }else { + ctEnabled=true; + } + if(cts.length>0) { + availableCarverTypes.add(cts[0]); + } for (int k = 0; k < cts.length; k++) { configCarverType(cts[k], carverTypeEl, CARVE_DIR_INDIVIDUAIS); - carverTypesArray.add(cts[k]); + cts[k].setEnabled(ctEnabled); + if(ctEnabled) { + enabledCarverTypes.add(cts[k]); + } + cts[k].id = ctid; } } @@ -155,6 +269,9 @@ public void loadXMLConfigFile(File confFile) throws IOException { } } + public void loadXMLConfigXML(File confFile) throws IOException { + } + private void configCarverType(CarverType ct, Element carverTypeEl, String scriptDir) { Element name = XMLUtil.getFirstElement(carverTypeEl, "name"); Element mediaType = XMLUtil.getFirstElement(carverTypeEl, "mediaType"); @@ -166,7 +283,7 @@ private void configCarverType(CarverType ct, Element carverTypeEl, String script Element maxLength = XMLUtil.getFirstElement(carverTypeEl, "maxLength"); Element carverScriptFile = XMLUtil.getFirstElement(carverTypeEl, "carverScriptFile"); Element stopOnNextHeader = XMLUtil.getFirstElement(carverTypeEl, "stopOnNextHeader"); - + if (name != null) { ct.setName(name.getTextContent()); } @@ -239,7 +356,15 @@ public boolean isToNotProcess(MediaType mediaType) { } public CarverType[] getCarverTypes() { - return carverTypesArray.toArray(new CarverType[0]); + return enabledCarverTypes.toArray(new CarverType[0]); + } + + public CarverType[] getAvailableCarverTypes() { + return availableCarverTypes.toArray(new CarverType[0]); + } + + public List getAvailableCarverTypesList() { + return availableCarverTypes; } /** @@ -249,7 +374,7 @@ public CarverType[] getCarverTypes() { synchronized public void configListener(CarvedItemListener carvedItemListener) throws CarverConfigurationException { try { - CarverType[] carverTypes = carverTypesArray.toArray(new CarverType[0]); + CarverType[] carverTypes = enabledCarverTypes.toArray(new CarverType[0]); if (tree == null) { tree = new AhoCorasick(); @@ -298,10 +423,54 @@ public HashMap getRegisteredCarvers() { public boolean isToIgnoreCorrupted() { return this.ignoreCorrupted; } + + public void setEnableCarverType(CarverType ct, boolean enabled) { + ct.setEnabled(enabled); + + NodeList ctNodes = mergedDoc.getElementsByTagName("carverType"); + for(int i=0; i")) { + return null; + } + return strResult; + } catch (TransformerException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return ""; } + public void reset() { + idseq = 0; + originalXmls.clear(); + TYPES_TO_PROCESS.clear(); + availableCarverTypes.clear(); + TYPES_TO_NOT_PROCESS.clear(); + TYPES_TO_CARVE.clear(); + enabledCarverTypes.clear(); + mergedDoc=null; + } + } \ No newline at end of file diff --git a/iped-engine/src/main/java/iped/engine/task/die/DIETask.java b/iped-engine/src/main/java/iped/engine/task/die/DIETask.java index 4c5aa71029..29db58d47c 100644 --- a/iped-engine/src/main/java/iped/engine/task/die/DIETask.java +++ b/iped-engine/src/main/java/iped/engine/task/die/DIETask.java @@ -116,7 +116,11 @@ public static void setEnabled(boolean enabled) { @Override public List> getConfigurables() { - return Arrays.asList(new EnableTaskProperty(ENABLE_PARAM)); + EnableTaskProperty result = ConfigurationManager.get().getEnableTaskPropertyObject(ENABLE_PARAM); + if(result == null) { + result = new EnableTaskProperty(ENABLE_PARAM); + } + return Arrays.asList(result); } /** diff --git a/iped-engine/src/main/java/iped/engine/task/index/ElasticSearchIndexTask.java b/iped-engine/src/main/java/iped/engine/task/index/ElasticSearchIndexTask.java index 533cf1da2a..11e04e2125 100644 --- a/iped-engine/src/main/java/iped/engine/task/index/ElasticSearchIndexTask.java +++ b/iped-engine/src/main/java/iped/engine/task/index/ElasticSearchIndexTask.java @@ -121,7 +121,11 @@ public boolean isEnabled() { } public List> getConfigurables() { - return Arrays.asList(new ElasticSearchTaskConfig()); + ElasticSearchTaskConfig result = ConfigurationManager.get().findObject(ElasticSearchTaskConfig.class); + if(result == null) { + result = new ElasticSearchTaskConfig(); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/index/IndexTask.java b/iped-engine/src/main/java/iped/engine/task/index/IndexTask.java index 8c3792bb76..214eac0251 100644 --- a/iped-engine/src/main/java/iped/engine/task/index/IndexTask.java +++ b/iped-engine/src/main/java/iped/engine/task/index/IndexTask.java @@ -239,7 +239,11 @@ private ParseContext getTikaContext(IItem evidence) { @Override public List> getConfigurables() { - return Arrays.asList(new IndexTaskConfig()); + IndexTaskConfig result = ConfigurationManager.get().findObject(IndexTaskConfig.class); + if(result == null) { + result = new IndexTaskConfig(); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/regex/RegexTask.java b/iped-engine/src/main/java/iped/engine/task/regex/RegexTask.java index 3fab274ad2..eed1d95135 100644 --- a/iped-engine/src/main/java/iped/engine/task/regex/RegexTask.java +++ b/iped-engine/src/main/java/iped/engine/task/regex/RegexTask.java @@ -168,7 +168,11 @@ public boolean isEnabled() { } public List> getConfigurables() { - return Arrays.asList(new RegexTaskConfig()); + RegexTaskConfig result = ConfigurationManager.get().findObject(RegexTaskConfig.class); + if(result == null) { + result = new RegexTaskConfig(); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/similarity/ImageSimilarityTask.java b/iped-engine/src/main/java/iped/engine/task/similarity/ImageSimilarityTask.java index 42a610700a..646aea723e 100644 --- a/iped-engine/src/main/java/iped/engine/task/similarity/ImageSimilarityTask.java +++ b/iped-engine/src/main/java/iped/engine/task/similarity/ImageSimilarityTask.java @@ -52,7 +52,11 @@ public static void setEnabled(boolean enabled) { @Override public List> getConfigurables() { - return Arrays.asList(new EnableTaskProperty(enableParam)); + EnableTaskProperty result = ConfigurationManager.get().getEnableTaskPropertyObject(enableParam); + if(result == null) { + result = new EnableTaskProperty(enableParam); + } + return Arrays.asList(result); } public void init(ConfigurationManager configurationManager) throws Exception { diff --git a/iped-engine/src/main/java/iped/engine/task/transcript/AbstractTranscriptTask.java b/iped-engine/src/main/java/iped/engine/task/transcript/AbstractTranscriptTask.java index 8c66a3c569..43d65a54ca 100644 --- a/iped-engine/src/main/java/iped/engine/task/transcript/AbstractTranscriptTask.java +++ b/iped-engine/src/main/java/iped/engine/task/transcript/AbstractTranscriptTask.java @@ -172,7 +172,11 @@ private void storeTextInDb(String id, String text, double score) throws IOExcept @Override public List> getConfigurables() { - return Arrays.asList(new AudioTranscriptConfig()); + AudioTranscriptConfig result = ConfigurationManager.get().findObject(AudioTranscriptConfig.class); + if(result == null) { + result = new AudioTranscriptConfig(); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/transcript/AudioTranscriptTask.java b/iped-engine/src/main/java/iped/engine/task/transcript/AudioTranscriptTask.java index ad07705e32..5f3662c5f5 100644 --- a/iped-engine/src/main/java/iped/engine/task/transcript/AudioTranscriptTask.java +++ b/iped-engine/src/main/java/iped/engine/task/transcript/AudioTranscriptTask.java @@ -15,7 +15,11 @@ public class AudioTranscriptTask extends AbstractTask { @Override public List> getConfigurables() { - return Arrays.asList(new AudioTranscriptConfig()); + AudioTranscriptConfig result = ConfigurationManager.get().findObject(AudioTranscriptConfig.class); + if(result == null) { + result = new AudioTranscriptConfig(); + } + return Arrays.asList(result); } @Override diff --git a/iped-engine/src/main/java/iped/engine/task/video/VideoThumbTask.java b/iped-engine/src/main/java/iped/engine/task/video/VideoThumbTask.java index bd331ce7f8..9010ed6c07 100644 --- a/iped-engine/src/main/java/iped/engine/task/video/VideoThumbTask.java +++ b/iped-engine/src/main/java/iped/engine/task/video/VideoThumbTask.java @@ -207,7 +207,11 @@ private static String normalizeMetadata(String meta) { } public List> getConfigurables() { - return Arrays.asList(new VideoThumbsConfig()); + VideoThumbsConfig result = ConfigurationManager.get().findObject(VideoThumbsConfig.class); + if(result == null) { + result = new VideoThumbsConfig(); + } + return Arrays.asList(result); } /** diff --git a/iped-engine/src/main/resources/iped/engine/task/carver/CarverConfig.xsd b/iped-engine/src/main/resources/iped/engine/task/carver/CarverConfig.xsd new file mode 100644 index 0000000000..ba5dc2914d --- /dev/null +++ b/iped-engine/src/main/resources/iped/engine/task/carver/CarverConfig.xsd @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/iped-geo/src/main/java/iped/geo/impl/MapPanelConfig.java b/iped-geo/src/main/java/iped/geo/impl/MapPanelConfig.java index 5f85248101..d00439bef1 100644 --- a/iped-geo/src/main/java/iped/geo/impl/MapPanelConfig.java +++ b/iped-geo/src/main/java/iped/geo/impl/MapPanelConfig.java @@ -1,6 +1,8 @@ package iped.geo.impl; +import java.io.File; import java.io.IOException; +import java.io.Writer; import java.nio.file.DirectoryStream; import java.nio.file.DirectoryStream.Filter; import java.nio.file.Path; @@ -10,6 +12,7 @@ import java.util.Set; import iped.configuration.Configurable; +import iped.engine.config.Configuration; import iped.utils.UTF8Properties; public class MapPanelConfig implements Configurable { @@ -87,4 +90,21 @@ public void setConfiguration(UTF8Properties config) { this.properties = config; } + @Override + public void save(Path resource) { + try { + File confDir = new File(resource.toFile(), Configuration.CONF_DIR); + confDir.mkdirs(); + File confFile = new File(confDir, GEO_CONFIG_FILE); + properties.store(confFile); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void reset() { + // TODO Auto-generated method stub + } + } diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/registry/RegRipperParser.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/registry/RegRipperParser.java index 31f1149858..1cfe7a9a1b 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/registry/RegRipperParser.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/registry/RegRipperParser.java @@ -50,7 +50,9 @@ public class RegRipperParser extends AbstractParser { */ private static final long serialVersionUID = 1L; - public static final String FULL_REPORT_SUFFIX = "_Full_Report"; + public static final String FULL_REPORT_SUFFIX = "_Full_Report";// this constant is redeclared in + // SearchHardwareWallets.py script and must be the + // same value there private static Logger LOGGER = LoggerFactory.getLogger(RegRipperParser.class); diff --git a/iped-utils/src/main/java/iped/utils/ProcessUtil.java b/iped-utils/src/main/java/iped/utils/ProcessUtil.java index 1ac27a8793..27e02c9e58 100644 --- a/iped-utils/src/main/java/iped/utils/ProcessUtil.java +++ b/iped-utils/src/main/java/iped/utils/ProcessUtil.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; +import java.util.prefs.Preferences; public class ProcessUtil { @@ -213,4 +214,16 @@ public static void killProcess(String name, String arg) { e.printStackTrace(); } } + + public static boolean isRunningAsAdmin() { + try { + Preferences preferences = Preferences.systemRoot(); + preferences.put("adminPrefTest", "value"); // SecurityException on Windows + preferences.remove("adminPrefTest"); + preferences.flush(); // BackingStoreException on Linux + return true; + } catch (Exception exception) { + return false; + } + } } diff --git a/iped-utils/src/main/java/iped/utils/UTF8Properties.java b/iped-utils/src/main/java/iped/utils/UTF8Properties.java index 81a6dccd84..ff7013b10a 100644 --- a/iped-utils/src/main/java/iped/utils/UTF8Properties.java +++ b/iped-utils/src/main/java/iped/utils/UTF8Properties.java @@ -1,14 +1,17 @@ package iped.utils; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; +import java.io.*; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; import java.util.Properties; +import java.util.Set; +import java.util.TreeMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Classe auxiliar que realiza leitura de propriedades em arquivos codificados @@ -22,24 +25,55 @@ public class UTF8Properties extends Properties { private static final long serialVersionUID = -8198271272010610933L; + boolean cumulative = false; + String cumulativeSeparator=";"; + + LinkedHashSet insertionOrder = new LinkedHashSet(); + HashMap comments = new HashMap(); + public synchronized void load(File file) throws IOException { - BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8")); //$NON-NLS-1$ - String str = null; - while ((str = in.readLine()) != null) { - if (str.isEmpty() || str.charAt(0) == '#') { - continue; - } - int pos = str.indexOf('='); - while (pos > 0 && str.charAt(pos - 1) == '\\') { - pos = str.indexOf('=', pos + 1); - } - if (pos > 0) { - String key = str.substring(0, pos).replace("\\=", "=").trim(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - String val = str.substring(pos + 1).replace("\\=", "=").trim(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - super.put(key, val); + try { + BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8")); //$NON-NLS-1$ + String str = null; + String lastComment=""; + boolean lastCommentSaved=false; + while ((str = in.readLine()) != null) { + if (str.trim().isEmpty() || str.trim().charAt(0) == '#') { + if(!str.trim().isEmpty()) { + if(lastCommentSaved) { + lastComment=""; + lastCommentSaved=false; + } + lastComment+=str.trim().substring(1)+"\n"; + } + continue; + } + int pos = str.indexOf('='); + while (pos > 0 && str.charAt(pos - 1) == '\\') { + pos = str.indexOf('=', pos + 1); + } + if (pos > 0) { + String key = str.substring(0, pos).replace("\\=", "=").replace("\\:", ":").trim(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + String val = str.substring(pos + 1).replace("\\=", "=").replace("\\:", ":").trim(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + if(isCumulative()) { + String valant = super.getProperty(key); + if(valant!=null) { + val = valant + cumulativeSeparator + val; + } + super.put(key, val); + }else { + super.put(key, val); + comments.put(key, lastComment); + lastCommentSaved=true; + } + + insertionOrder.add(key); + } } + in.close(); + }catch (FileNotFoundException e) { + //ignores } - in.close(); } public synchronized void store(File file) throws IOException { @@ -52,4 +86,142 @@ public synchronized void store(File file) throws IOException { } writer.close(); } + + public synchronized void storeAndPreserve(File file) throws IOException { + OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file), "UTF-8"); //$NON-NLS-1$ + Object[] keys = this.keySet().toArray(); + Arrays.sort(keys); + for (Object key : keys) { + writer.write(key.toString().replace("=", "\\=") + " = " + this.get(key).toString().replace("=", "\\=")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + writer.write("\r\n"); //$NON-NLS-1$ + } + writer.close(); + } + + public synchronized void saveOnFile(File fileToBeChanged) throws IOException { + BufferedReader reader = null; + FileWriter writer = null; + Charset UTF8 = Charset.forName("UTF-8"); + + try{ + reader = new BufferedReader(new FileReader(fileToBeChanged, UTF8)); + + //Read all file lines and put on a StringBuffer + String line = reader.readLine(); + StringBuffer fileContent = new StringBuffer(); + while (line != null){ + fileContent.append(line).append(System.lineSeparator()); + line = reader.readLine(); + } + + //Iterate over all properties key ant set value on filecontent + String changedContent = fileContent.toString(); + for(Object key : this.keySet()) { + //Try to find the propertie Key + Matcher matcher = getPropertieKeyRegexPattern(key.toString()).matcher(changedContent); + if (!matcher.find()) + continue; + //If propertie key exists, change the propertie value + //Whe need to use Matcher.quoteReplacement to prevent + final String subst = "$1= " + Matcher.quoteReplacement( String.valueOf(this.get(key)) ); + changedContent = matcher.replaceAll(subst); + } + + //save the file content + writer = new FileWriter(fileToBeChanged, UTF8); + writer.write(changedContent); + }finally{ + try{ + //Close all resources + if(reader != null) + reader.close(); + if(writer != null){ + writer.flush(); + writer.close(); + } + }catch (IOException e){ + e.printStackTrace(); + } + } + } + + public synchronized void enableOrDisablePropertie(File fileToBeChanged, String propertieName, Boolean isDisable){ + String fileContent = ""; + BufferedReader reader = null; + FileWriter writer = null; + + try{ + reader = new BufferedReader(new FileReader(fileToBeChanged, StandardCharsets.UTF_8)); + + //Read all file content and set on fileContent var + String line = reader.readLine(); + while (line != null){ + fileContent = fileContent + line + System.lineSeparator(); + line = reader.readLine(); + } + + String conteudoModificado = fileContent ; + //is option is to disablePropertie + if (isDisable){ + String chaveComentada = "#" + propertieName; + //analisa se a chave ja esta comentada para que não adicione mais um # + if( ! fileContent.contains(chaveComentada) ) + conteudoModificado = fileContent.replaceAll(propertieName, chaveComentada); + } else { + conteudoModificado = fileContent.replaceAll("#"+propertieName, propertieName); + } + + //Save modification on file + writer = new FileWriter(fileToBeChanged, StandardCharsets.UTF_8); + writer.write(conteudoModificado); + }catch (IOException e){ + e.printStackTrace(); + }finally{ + try{ + //Fechando os recursos + if(reader != null) + reader.close(); + if(writer != null){ + writer.flush(); + writer.close(); + } + }catch (IOException e){ + e.printStackTrace(); + } + } + } + + private Pattern getPropertieKeyRegexPattern(String key){ + //Regex to find a propertie key on a String + final String regex = "(^\\s*#*\\s*"+ key +"\\s*)=(.*)"; + return Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + } + + public boolean isCumulative() { + return cumulative; + } + + public void setCumulative(boolean cumulative) { + this.cumulative = cumulative; + } + + public String getCumulativeSeparator() { + return cumulativeSeparator; + } + + public void setCumulativeSeparator(String cumulativeSeparator) { + this.cumulativeSeparator = cumulativeSeparator; + } + + public Set orderedKeySet() { + if(insertionOrder.size()!=this.size()) { + return super.keySet(); + } + return insertionOrder; + } + + public String getComments(Object key) { + return comments.get(key); + } + } diff --git a/iped-utils/src/main/java/iped/utils/XMLUtil.java b/iped-utils/src/main/java/iped/utils/XMLUtil.java index e369bb80df..e875847af2 100644 --- a/iped-utils/src/main/java/iped/utils/XMLUtil.java +++ b/iped-utils/src/main/java/iped/utils/XMLUtil.java @@ -4,6 +4,8 @@ import org.w3c.dom.NodeList; public class XMLUtil { + + public static final String IPED_NAMESAPCE = "https://github.com/sepinf-inc/IPED"; static public Element getFirstElement(Element el, String tagName) { NodeList snl = el.getElementsByTagName(tagName); diff --git a/iped-utils/src/main/java/iped/utils/ui/ScreenUtils.java b/iped-utils/src/main/java/iped/utils/ui/ScreenUtils.java new file mode 100644 index 0000000000..d4e0eaabd3 --- /dev/null +++ b/iped-utils/src/main/java/iped/utils/ui/ScreenUtils.java @@ -0,0 +1,61 @@ +package iped.utils.ui; + +import javax.swing.*; +import java.awt.*; + +/** + * @created 05/09/2022 + * @project IPED + * @author Thiago S. Figueiredo + * + * Utility class to manage frame positioning on multiple monitors + */ +public class ScreenUtils { + + /** + * Place frame on the given Monitor/Screen + * @param screen - Number of target Monitor/Screen + * @param frame - JFrame references to be managed + */ + public static void showOnScreen(int screen, JFrame frame ) { + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice[] gd = ge.getScreenDevices(); + int width, height; + if( screen > -1 && screen < gd.length ) { + width = gd[screen].getDefaultConfiguration().getBounds().width; + height = gd[screen].getDefaultConfiguration().getBounds().height; + frame.setLocation( + ((width / 2) - (frame.getSize().width / 2)) + gd[screen].getDefaultConfiguration().getBounds().x, + ((height / 2) - (frame.getSize().height / 2)) + gd[screen].getDefaultConfiguration().getBounds().y + ); + frame.setVisible(true); + } else { + throw new RuntimeException( "No Screens/Monitors Found" ); + } + } + + /** + * Place frame on the given Monitor/Screen with margins + * @param screen - Number of target Monitor/Screen + * @param frame - JFrame references to be managed + * @param marginx - Horizontal margin + * @param marginy - Vertical margin + */ + public static void showOnScreen(int screen, JFrame frame, int marginx, int marginy) { + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice[] gd = ge.getScreenDevices(); + int width, height; + if( screen > -1 && screen < gd.length ) { + width = gd[screen].getDefaultConfiguration().getBounds().width; + height = gd[screen].getDefaultConfiguration().getBounds().height; + frame.setLocation( + ((width / 2) - (frame.getSize().width / 2) + marginx) + gd[screen].getDefaultConfiguration().getBounds().x, + ((height / 2) - (frame.getSize().height / 2) + marginy) + gd[screen].getDefaultConfiguration().getBounds().y + ); + frame.setVisible(true); + } else { + throw new RuntimeException( "No Screens/Monitors Found" ); + } + } + +}