diff --git a/src/main/java/com/formdev/flatlaf/intellijthemes/IJThemesDuplicateNameChecker.java b/src/main/java/com/formdev/flatlaf/intellijthemes/IJThemesDuplicateNameChecker.java new file mode 100644 index 0000000..8dda871 --- /dev/null +++ b/src/main/java/com/formdev/flatlaf/intellijthemes/IJThemesDuplicateNameChecker.java @@ -0,0 +1,72 @@ +/* + * Copyright 2021 FormDev Software GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.formdev.flatlaf.intellijthemes; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.StandardCharsets; +import java.util.HashSet; +import java.util.Map; +import com.formdev.flatlaf.json.Json; +import com.formdev.flatlaf.json.ParseException; + +/** + * This tool checks whether there are duplicate name fields in all theme .json files. + * + * This is important for following file, where the name is used for theme specific UI defaults: + * flatlaf-core/src/main/resources/com/formdev/flatlaf/IntelliJTheme$ThemeLaf.properties + * + * @author Karl Tauber + */ +public class IJThemesDuplicateNameChecker +{ + public static void main( String[] args ) { + IJThemesManager themesManager = new IJThemesManager(); + themesManager.loadBundledThemes(); + + HashSet names = new HashSet<>(); + for( IJThemeInfo ti : themesManager.bundledThemes ) { + if( ti.sourceCodeUrl == null || ti.sourceCodePath == null ) + continue; + + String jsonPath = "../flatlaf-intellij-themes/src/main/resources" + IJThemesPanel.THEMES_PACKAGE + ti.resourceName; + String name; + try { + name = readNameFromJson( jsonPath ); + } catch( IOException ex ) { + System.err.println( "Failed to read '" + jsonPath + "'" ); + continue; + } + + if( names.contains( name ) ) + System.out.println( "Duplicate name '" + name + "'" ); + names.add( name ); + } + } + + private static String readNameFromJson( String jsonPath ) throws IOException { + try( Reader reader = new InputStreamReader( new FileInputStream( jsonPath ), StandardCharsets.UTF_8 ) ) { + @SuppressWarnings( "unchecked" ) + Map json = (Map) Json.parse( reader ); + return (String) json.get( "name" ); + } catch( ParseException ex ) { + throw new IOException( ex.getMessage(), ex ); + } + } +} diff --git a/src/main/java/com/formdev/flatlaf/intellijthemes/IJThemesManager.java b/src/main/java/com/formdev/flatlaf/intellijthemes/IJThemesManager.java new file mode 100644 index 0000000..095fa9e --- /dev/null +++ b/src/main/java/com/formdev/flatlaf/intellijthemes/IJThemesManager.java @@ -0,0 +1,104 @@ +/* + * Copyright 2019 FormDev Software GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.formdev.flatlaf.intellijthemes; + +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import com.formdev.flatlaf.json.Json; +import com.formdev.flatlaf.util.LoggingFacade; +import com.formdev.flatlaf.util.StringUtils; + +/** + * @author Karl Tauber + */ +class IJThemesManager +{ + final List bundledThemes = new ArrayList<>(); + final List moreThemes = new ArrayList<>(); + private final Map lastModifiedMap = new HashMap<>(); + + @SuppressWarnings( "unchecked" ) + void loadBundledThemes() { + bundledThemes.clear(); + + // load themes.json + Map json; + try( Reader reader = new InputStreamReader( getClass().getResourceAsStream( "themes.json" ), StandardCharsets.UTF_8 ) ) { + json = (Map) Json.parse( reader ); + } catch( IOException ex ) { + LoggingFacade.INSTANCE.logSevere( null, ex ); + return; + } + + // add info about bundled themes + for( Map.Entry e : json.entrySet() ) { + String resourceName = e.getKey(); + Map value = (Map) e.getValue(); + String name = value.get( "name" ); + boolean discontinued = Boolean.parseBoolean( value.get( "discontinued" ) ); + boolean dark = Boolean.parseBoolean( value.get( "dark" ) ); + String lafClassName = value.get( "lafClassName" ); + String license = value.get( "license" ); + String licenseFile = value.get( "licenseFile" ); + String pluginUrl = value.get( "pluginUrl" ); + String sourceCodeUrl = value.get( "sourceCodeUrl" ); + String sourceCodePath = value.get( "sourceCodePath" ); + + bundledThemes.add( new IJThemeInfo( name, resourceName, discontinued, dark, + license, licenseFile, pluginUrl, sourceCodeUrl, sourceCodePath, null, lafClassName ) ); + } + } + + void loadThemesFromDirectory() { + // get current working directory + File directory = new File( "" ).getAbsoluteFile(); + + File[] themeFiles = directory.listFiles( (dir, name) -> { + return name.endsWith( ".theme.json" ) || name.endsWith( ".properties" ); + } ); + if( themeFiles == null ) + return; + + lastModifiedMap.clear(); + lastModifiedMap.put( directory, directory.lastModified() ); + + moreThemes.clear(); + for( File f : themeFiles ) { + String fname = f.getName(); + String name = fname.endsWith( ".properties" ) + ? StringUtils.removeTrailing( fname, ".properties" ) + : StringUtils.removeTrailing( fname, ".theme.json" ); + moreThemes.add( new IJThemeInfo( name, null, false, false, null, null, null, null, null, f, null ) ); + lastModifiedMap.put( f, f.lastModified() ); + } + } + + boolean hasThemesFromDirectoryChanged() { + for( Map.Entry e : lastModifiedMap.entrySet() ) { + if( e.getKey().lastModified() != e.getValue().longValue() ) + return true; + } + return false; + } +}