View Javadoc

1   /*
2    * #%L
3    * xcode-maven-plugin
4    * %%
5    * Copyright (C) 2012 SAP AG
6    * %%
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   * 
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   * 
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * #L%
19   */
20  package com.sap.prd.mobile.ios.mios;
21  
22  import static org.apache.commons.io.IOUtils.closeQuietly;
23  
24  import java.io.BufferedReader;
25  import java.io.File;
26  import java.io.FileNotFoundException;
27  import java.io.IOException;
28  import java.io.InputStream;
29  import java.io.StringReader;
30  import java.nio.charset.Charset;
31  import java.util.Scanner;
32  
33  import org.apache.commons.io.IOUtils;
34  import org.apache.commons.lang.StringUtils;
35  
36  public class PListAccessor
37  {
38    public static final String KEY_BUNDLE_IDENTIFIER = "CFBundleIdentifier";
39    public static final String KEY_BUNDLE_VERSION = "CFBundleVersion";
40    public static final String KEY_BUNDLE_SHORT_VERSION_STRING = "CFBundleShortVersionString";
41    public static final String KEY_WK_COMPANION_APP_BUNDLE_IDENTIFIER ="WKCompanionAppBundleIdentifier";
42    public static final String KEY_WK_APP_BUNDLE_IDENTIFIER ="NSExtension:NSExtensionAttributes:WKAppBundleIdentifier";
43  
44    private final File plist;
45  
46    public PListAccessor(File file)
47    {
48      plist = file;
49    }
50  
51    public File getPlistFile()
52    {
53      return plist;
54    }
55  
56    public String getStringValue(String key) throws IOException
57    {
58      if (!plist.exists())
59      {
60        throw new FileNotFoundException("The Plist " + plist.getAbsolutePath() + " does not exist.");
61      }
62  
63      try
64      {
65        String command = "/usr/libexec/PlistBuddy -c \"Print :" + key + "\" \"" + plist.getAbsolutePath() + "\"";
66  
67        System.out.println("[INFO] PlistBuddy Print command is: '" + command + "'.");
68  
69        String[] args = new String[] { "bash", "-c", command };
70        Process p = Runtime.getRuntime().exec(args);
71        p.waitFor();
72  
73        int exitValue = p.exitValue();
74  
75        if (exitValue == 0)
76        {
77          InputStream is = p.getInputStream();
78          try {
79            return new Scanner(is, Charset.defaultCharset().name()).useDelimiter("\\Z").next();
80          }
81          finally {
82            closeQuietly(is);
83          }
84        }
85  
86        String errorMessage = "<n/a>";
87  
88        try {
89          errorMessage = new Scanner(p.getErrorStream(), Charset.defaultCharset().name()).useDelimiter("\\Z").next();
90        }
91        catch (Exception ex) {
92          System.out.println("[ERROR] Exception caught during retrieving error message of command '" + command + "': "
93                + ex);
94        }
95  
96        if (errorMessage.contains(":" + key + "\", Does Not Exist")) {
97          // ugly string parsing above, but no other known way ...
98          return null;
99        }
100 
101       throw new IllegalStateException("Execution of \"" + StringUtils.join(args, " ")
102             + "\" command failed. Error message is: " + errorMessage + ". Return code was: '" + exitValue + "'.");
103     }
104     catch (InterruptedException e)
105     {
106       throw new RuntimeException(e);
107     }
108   }
109 
110   public void updateStringValue(String key, String value) throws IOException
111   {
112     if (!plist.exists())
113     {
114       throw new FileNotFoundException("Plist file '" + plist + "' not found.");
115     }
116 
117     try
118     {
119       String command = "/usr/libexec/PlistBuddy -x -c \"Set :" + key + " " + value + "\" \"" + plist.getAbsolutePath()
120             + "\"";
121       System.out.println("[INFO] PlistBuddy Set command is: '" + command + "'.");
122       String[] args = new String[] { "bash", "-c", command };
123       Process p = Runtime.getRuntime().exec(args);
124       p.waitFor();
125       int exitValue = p.exitValue();
126       if (exitValue != 0)
127       {
128         String errorMessage = "n/a";
129         try {
130           errorMessage = new Scanner(p.getErrorStream(), Charset.defaultCharset().name()).useDelimiter("\\Z").next();
131         }
132         catch (Exception ex) {
133           System.out.println("[ERROR] Exception caught during retrieving error message of command '" + command + "': "
134                 + ex);
135         }
136         throw new IllegalStateException("Execution of \"" + StringUtils.join(args, " ") + "\" command failed: "
137               + errorMessage + ". Exit code was: " + exitValue);
138       }
139     }
140     catch (InterruptedException e)
141     {
142       throw new RuntimeException(e);
143     }
144   }
145 
146   public void addStringValue(String key, String value) throws IOException
147   {
148     if (!plist.exists())
149     {
150       throw new FileNotFoundException("Plist file '" + plist + "' not found.");
151     }
152 
153     try
154     {
155       String command = "/usr/libexec/PlistBuddy -x -c \"Add :" + key + " string " + value + "\" \""
156             + plist.getAbsolutePath() + "\"";
157       System.out.println("[INFO] PlistBuddy Add command is: '" + command + "'.");
158       String[] args = new String[] { "bash", "-c", command };
159       Process p = Runtime.getRuntime().exec(args);
160       p.waitFor();
161       int exitValue = p.exitValue();
162       if (exitValue != 0)
163       {
164         String errorMessage = "n/a";
165         try {
166           errorMessage = new Scanner(p.getErrorStream(), Charset.defaultCharset().name()).useDelimiter("\\Z").next();
167         }
168         catch (Exception ex) {
169           System.out.println("[ERROR] Exception caught during retrieving error message of command '" + command + "': "
170                 + ex);
171         }
172         throw new IllegalStateException("Execution of \"" + StringUtils.join(args, " ") + "\" command failed: "
173               + errorMessage + ". Exit code was: " + exitValue);
174       }
175     }
176     catch (InterruptedException e)
177     {
178       throw new RuntimeException(e);
179     }
180   }
181 
182   public void addStringValueToDict(String key, String value, String dictKey) throws IOException
183   {
184     if (!plist.exists())
185     {
186       throw new FileNotFoundException("Plist file '" + plist + "' not found.");
187     }
188 
189     try
190     {
191       String command = "/usr/libexec/PlistBuddy -x -c \"Add :" + dictKey + ":" + key + " string " + value + "\" \""
192             + plist.getAbsolutePath() + "\"";
193       System.out.println("[INFO] PlistBuddy Add command is: '" + command + "'.");
194       String[] args = new String[] { "bash", "-c", command };
195       Process p = Runtime.getRuntime().exec(args);
196       p.waitFor();
197       int exitValue = p.exitValue();
198       if (exitValue != 0)
199       {
200         String errorMessage = "n/a";
201         try {
202           errorMessage = new Scanner(p.getErrorStream(), Charset.defaultCharset().name()).useDelimiter("\\Z").next();
203         }
204         catch (Exception ex) {
205           System.out.println("[ERROR] Exception caught during retrieving error message of command '" + command + "': "
206                 + ex);
207         }
208         throw new IllegalStateException("Execution of \"" + StringUtils.join(args, " ") + "\" command failed: "
209               + errorMessage + ". Exit code was: " + exitValue);
210       }
211     }
212     catch (InterruptedException e)
213     {
214       throw new RuntimeException(e);
215     }
216   }
217 
218   public void addElement(String key, String type) throws IOException
219   {
220     if (!plist.exists())
221     {
222       throw new FileNotFoundException("Plist file '" + plist + "' not found.");
223     }
224     try
225     {
226       String command = "/usr/libexec/PlistBuddy -x -c \"Add :" + key + " " + type + "  " + "\" \""
227             + plist.getAbsolutePath() + "\"";
228       System.out.println("[INFO] PlistBuddy Add command is: '" + command + "'.");
229       String[] args = new String[] { "bash", "-c", command };
230       Process p = Runtime.getRuntime().exec(args);
231       p.waitFor();
232       int exitValue = p.exitValue();
233       if (exitValue != 0)
234       {
235         String errorMessage = "n/a";
236         try {
237           errorMessage = new Scanner(p.getErrorStream(), Charset.defaultCharset().name()).useDelimiter("\\Z").next();
238         }
239         catch (Exception ex) {
240           System.out.println("[ERROR] Exception caught during retrieving error message of command '" + command + "': "
241                 + ex);
242         }
243         throw new IllegalStateException("Execution of \"" + StringUtils.join(args, " ") + "\" command failed: "
244               + errorMessage + ". Exit code was: " + exitValue);
245       }
246     }
247     catch (InterruptedException e)
248     {
249       throw new RuntimeException(e);
250     }
251   }
252 
253   public void addDictToArray(String dict, String array) throws IOException
254   {
255     if (!plist.exists())
256     {
257       throw new FileNotFoundException("Plist file '" + plist + "' not found.");
258     }
259 
260     try
261     {
262       String command = "/usr/libexec/PlistBuddy -x -c \"Add :" + array + ":" + dict + " dict " + "\" \""
263             + plist.getAbsolutePath() + "\"";
264       System.out.println("[INFO] PlistBuddy Add command is: '" + command + "'.");
265       String[] args = new String[] { "bash", "-c", command };
266       Process p = Runtime.getRuntime().exec(args);
267       p.waitFor();
268       int exitValue = p.exitValue();
269       if (exitValue != 0)
270       {
271         String errorMessage = "n/a";
272         try {
273           errorMessage = new Scanner(p.getErrorStream(), Charset.defaultCharset().name()).useDelimiter("\\Z").next();
274         }
275         catch (Exception ex) {
276           System.out.println("[ERROR] Exception caught during retrieving error message of command '" + command + "': "
277                 + ex);
278         }
279         throw new IllegalStateException("Execution of \"" + StringUtils.join(args, " ") + "\" command failed: "
280               + errorMessage + ". Exit code was: " + exitValue);
281       }
282     }
283     catch (InterruptedException e)
284     {
285       throw new RuntimeException(e);
286     }
287   }
288 
289   public void createPlist() throws IOException
290   {
291 
292     try
293     {
294       String command = "/usr/libexec/PlistBuddy -x -c \"Save \" \"" + plist.getAbsolutePath() + "\"";
295       System.out.println("[INFO] PlistBuddy Add command is: '" + command + "'.");
296       String[] args = new String[] { "bash", "-c", command };
297 
298       Process p = Runtime.getRuntime().exec(args);
299 
300       p.waitFor();
301 
302       int exitValue = p.exitValue();
303 
304       if (exitValue != 0)
305       {
306         String errorMessage = "n/a";
307         try {
308           errorMessage = new Scanner(p.getErrorStream(), Charset.defaultCharset().name()).useDelimiter("\\Z").next();
309         }
310         catch (Exception ex) {
311           System.out.println("[ERROR] Exception caught during retrieving error message of command '" + command + "': "
312                 + ex);
313         }
314         throw new IllegalStateException("Execution of \"" + StringUtils.join(args, " ") + "\" command failed: "
315               + errorMessage + ". Exit code was: " + exitValue);
316       }
317     }
318     catch (InterruptedException e)
319     {
320       throw new RuntimeException(e);
321     }
322   }
323 
324   public String printValue(String key) throws IOException
325   {
326 
327     try
328     {
329       String command = "/usr/libexec/PlistBuddy -c \"Print :" + key + "\" \"" + plist.getAbsolutePath() + "\"";
330       System.out.println("[INFO] PlistBuddy Add command is: '" + command + "'.");
331       String[] args = new String[] { "bash", "-c", command };
332 
333       Process p = Runtime.getRuntime().exec(args);
334 
335       InputStream is = p.getInputStream();
336       p.waitFor();
337       int exitValue = p.exitValue();
338 
339       if (exitValue != 0)
340       {
341         String errorMessage = "n/a";
342         try {
343           errorMessage = new Scanner(p.getErrorStream(), Charset.defaultCharset().name()).useDelimiter("\\Z").next();
344         }
345         catch (Exception ex) {
346           System.out.println("[ERROR] Exception caught during retrieving error message of command '" + command + "': "
347                 + ex);
348         }
349         throw new IllegalStateException("Execution of \"" + StringUtils.join(args, " ") + "\" command failed: "
350               + errorMessage + ". Exit code was: " + exitValue);
351       }
352 
353       byte[] buff = new byte[64];
354       StringBuilder sb = new StringBuilder();
355       for (int i = 0; (i = is.read(buff)) != -1;) {
356         sb.append(new String(buff, 0, i, Charset.defaultCharset().name()));
357       }
358       BufferedReader reader = new BufferedReader(new StringReader(sb.toString()));
359 
360       try {
361         return reader.readLine();
362       }
363       finally {
364         IOUtils.closeQuietly(reader);
365       }
366     }
367 
368     catch (InterruptedException e)
369     {
370       throw new RuntimeException(e);
371     }
372   }
373 
374 }