1212import org .jd .core .v1 .ClassFileToJavaSourceDecompiler ;
1313import org .jd .gui .api .API ;
1414import org .jd .gui .api .model .Container ;
15- import org .jd .gui .util .decompiler .ClassPathLoader ;
16- import org .jd .gui .util .decompiler .ContainerLoader ;
17- import org .jd .gui .util .decompiler .NopPrinter ;
18- import org .jd .gui .util .decompiler .StringBuilderPrinter ;
15+ import org .jd .gui .util .decompiler .*;
1916import org .jd .gui .util .exception .ExceptionUtil ;
17+ import org .jd .gui .util .io .NewlineOutputStream ;
2018
2119import javax .swing .text .BadLocationException ;
2220import javax .swing .text .DefaultCaret ;
2321import java .awt .*;
22+ import java .io .*;
23+ import java .nio .charset .Charset ;
2424import java .util .HashMap ;
2525import java .util .Map ;
2626
2727public class ClassFilePage extends TypePage {
2828 protected static final String ESCAPE_UNICODE_CHARACTERS = "ClassFileDecompilerPreferences.escapeUnicodeCharacters" ;
2929 protected static final String REALIGN_LINE_NUMBERS = "ClassFileDecompilerPreferences.realignLineNumbers" ;
30+ protected static final String WRITE_LINE_NUMBERS = "ClassFileSaverPreferences.writeLineNumbers" ;
31+ protected static final String WRITE_METADATA = "ClassFileSaverPreferences.writeMetadata" ;
32+ protected static final String JD_CORE_VERSION = "JdGuiPreferences.jdCoreVersion" ;
3033
3134 protected static final ClassFileToJavaSourceDecompiler DECOMPILER = new ClassFileToJavaSourceDecompiler ();
3235
@@ -97,18 +100,102 @@ protected static boolean getPreferenceValue(Map<String, String> preferences, Str
97100 return (v == null ) ? defaultValue : Boolean .valueOf (v );
98101 }
99102
103+ @ Override
100104 public String getSyntaxStyle () { return SyntaxConstants .SYNTAX_STYLE_JAVA ; }
101105
102106 // --- ContentSavable --- //
107+ @ Override
103108 public String getFileName () {
104109 String path = entry .getPath ();
105110 int index = path .lastIndexOf ('.' );
106111 return path .substring (0 , index ) + ".java" ;
107112 }
108113
114+ @ Override
115+ public void save (API api , OutputStream os ) {
116+ try {
117+ // Init preferences
118+ Map <String , String > preferences = api .getPreferences ();
119+ boolean realignmentLineNumbers = getPreferenceValue (preferences , REALIGN_LINE_NUMBERS , true );
120+ boolean unicodeEscape = getPreferenceValue (preferences , ESCAPE_UNICODE_CHARACTERS , false );
121+ boolean showLineNumbers = getPreferenceValue (preferences , WRITE_LINE_NUMBERS , true );
122+
123+ Map <String , Object > configuration = new HashMap <>();
124+ configuration .put ("realignLineNumbers" , realignmentLineNumbers );
125+
126+ // Init loader
127+ ContainerLoader loader = new ContainerLoader (entry );
128+
129+ // Init printer
130+ LineNumberStringBuilderPrinter printer = new LineNumberStringBuilderPrinter ();
131+ printer .setRealignmentLineNumber (realignmentLineNumbers );
132+ printer .setUnicodeEscape (unicodeEscape );
133+ printer .setShowLineNumbers (showLineNumbers );
134+
135+ // Format internal name
136+ String entryPath = entry .getPath ();
137+ assert entryPath .endsWith (".class" );
138+ String entryInternalName = entryPath .substring (0 , entryPath .length () - 6 ); // 6 = ".class".length()
139+
140+ // Decompile class file
141+ DECOMPILER .decompile (loader , printer , entryInternalName , configuration );
142+
143+ StringBuilder stringBuffer = printer .getStringBuffer ();
144+
145+ // Metadata
146+ if (getPreferenceValue (preferences , WRITE_METADATA , true )) {
147+ // Add location
148+ String location =
149+ new File (entry .getUri ()).getPath ()
150+ // Escape "\ u" sequence to prevent "Invalid unicode" errors
151+ .replaceAll ("(^|[^\\ \\ ])\\ \\ u" , "\\ \\ \\ \\ u" );
152+ stringBuffer .append ("\n \n /* Location: " );
153+ stringBuffer .append (location );
154+ // Add Java compiler version
155+ int majorVersion = printer .getMajorVersion ();
156+
157+ if (majorVersion >= 45 ) {
158+ stringBuffer .append ("\n * Java compiler version: " );
159+
160+ if (majorVersion >= 49 ) {
161+ stringBuffer .append (majorVersion - (49 - 5 ));
162+ } else {
163+ stringBuffer .append (majorVersion - (45 - 1 ));
164+ }
165+
166+ stringBuffer .append (" (" );
167+ stringBuffer .append (majorVersion );
168+ stringBuffer .append ('.' );
169+ stringBuffer .append (printer .getMinorVersion ());
170+ stringBuffer .append (')' );
171+ }
172+ // Add JD-Core version
173+ stringBuffer .append ("\n * JD-Core Version: " );
174+ stringBuffer .append (preferences .get (JD_CORE_VERSION ));
175+ stringBuffer .append ("\n */" );
176+ }
177+
178+ try (PrintStream ps = new PrintStream (new NewlineOutputStream (os ), true , "UTF-8" )) {
179+ ps .print (stringBuffer .toString ());
180+ } catch (IOException e ) {
181+ assert ExceptionUtil .printStackTrace (e );
182+ }
183+ } catch (Throwable t ) {
184+ assert ExceptionUtil .printStackTrace (t );
185+
186+ try (OutputStreamWriter writer = new OutputStreamWriter (os , Charset .defaultCharset ())) {
187+ writer .write ("// INTERNAL ERROR //" );
188+ } catch (IOException ee ) {
189+ assert ExceptionUtil .printStackTrace (ee );
190+ }
191+ }
192+ }
193+
109194 // --- LineNumberNavigable --- //
195+ @ Override
110196 public int getMaximumLineNumber () { return maximumLineNumber ; }
111197
198+ @ Override
112199 public void goToLineNumber (int lineNumber ) {
113200 int textAreaLineNumber = getTextAreaLineNumber (lineNumber );
114201 if (textAreaLineNumber > 0 ) {
@@ -122,9 +209,11 @@ public void goToLineNumber(int lineNumber) {
122209 }
123210 }
124211
212+ @ Override
125213 public boolean checkLineNumber (int lineNumber ) { return lineNumber <= maximumLineNumber ; }
126214
127215 // --- PreferencesChangeListener --- //
216+ @ Override
128217 public void preferencesChanged (Map <String , String > preferences ) {
129218 DefaultCaret caret = (DefaultCaret )textArea .getCaret ();
130219 int updatePolicy = caret .getUpdatePolicy ();
@@ -220,6 +309,7 @@ public void endLine() {
220309 super .endLine ();
221310 textAreaLineNumber ++;
222311 }
312+ @ Override
223313 public void extraLine (int count ) {
224314 super .extraLine (count );
225315 if (realignmentLineNumber ) {
0 commit comments