View Javadoc

1   package net.sourceforge.simplegamenet.framework;
2   
3   import java.io.File;
4   import java.io.FileFilter;
5   import java.net.MalformedURLException;
6   import java.net.URI;
7   import java.net.URISyntaxException;
8   import java.net.URL;
9   import java.net.URLClassLoader;
10  import java.util.ArrayList;
11  import java.util.Collections;
12  import java.util.Iterator;
13  import java.util.List;
14  import java.util.jar.JarFile;
15  import java.util.jar.Manifest;
16  import javax.swing.*;
17  import net.sourceforge.simplegamenet.framework.model.SimpleGameNetSettings;
18  import net.sourceforge.simplegamenet.framework.transport.GameIdentification;
19  import net.sourceforge.simplegamenet.specs.model.GameFactory;
20  
21  /***
22   * A Singleton
23   */
24  public class GameFactoryManager {
25  
26      private static GameFactoryManager instance;
27  
28      public static GameFactoryManager getInstance() {
29          return instance;
30      }
31  
32      public static void loadGamesStaticly(List gameFactoriesList) {
33          ClassLoader gamesClassLoader = GameFactoryManager.class.getClassLoader();
34          instance = new GameFactoryManager(gamesClassLoader, gameFactoriesList);
35      }
36  
37      public static void loadGamesDynamically() {
38          try {
39              String gamesPath = createGamesPath();
40              File pathFile = new File(new URI(gamesPath));
41              File[] files = pathFile.listFiles(new JarFileFilter());
42              if (files == null) {
43                  JOptionPane.showMessageDialog(null,
44                          pathFile.toString() + " does not exist.",
45                          "Error loading games", JOptionPane.ERROR_MESSAGE);
46                  System.exit(1);
47              }
48              ClassLoader gamesClassLoader = createGamesClassLoader(files, gamesPath);
49              List gameFactoriesList = createGameFactoriesList(files, gamesClassLoader, pathFile);
50              Collections.sort(gameFactoriesList);
51              Thread.currentThread().setContextClassLoader(gamesClassLoader);
52              instance = new GameFactoryManager(gamesClassLoader, gameFactoriesList);
53          } catch (URISyntaxException e) {
54              JOptionPane.showMessageDialog(null,
55                      "Error loading games.",
56                      "Error loading games", JOptionPane.ERROR_MESSAGE);
57              System.exit(1);
58          }
59      }
60  
61      private static String createGamesPath() {
62          String gamesPath = GameFactoryManager.class.getResource(
63                  "/" + GameFactoryManager.class.getName().replaceAll("//.", "/") + ".class")
64                  .getPath();
65          gamesPath = gamesPath.substring(0, gamesPath.lastIndexOf('/', gamesPath.lastIndexOf('!')))
66                  + "/games/";
67          return gamesPath;
68  
69      }
70  
71      private static ClassLoader createGamesClassLoader(File[] files, String path) {
72          URL[] uRLs = new URL[files.length];
73          for (int i = 0; i < files.length; i++) {
74              try {
75                  uRLs[i] = new URL(new URL(path), files[i].getName());
76              } catch (MalformedURLException e) {
77                  e.printStackTrace();
78              }
79          }
80          ClassLoader gamesClassLoader = new URLClassLoader(uRLs);
81          return gamesClassLoader;
82      }
83  
84      private static List createGameFactoriesList(File[] files, ClassLoader gamesClassLoader,
85                                                  File pathFile) {
86          List gameFactoriesList;
87          gameFactoriesList = new ArrayList();
88          for (int i = 0; i < files.length; i++) {
89              try {
90                  JarFile jarFile = new JarFile(files[i]);
91                  Manifest manifest = jarFile.getManifest();
92                  if (manifest == null) {
93                      throw new Exception("No manifest");
94                  }
95                  Class classInstance = gamesClassLoader.loadClass(
96                          manifest.getMainAttributes().getValue("Main-Class"));
97                  GameFactory gameFactory = (GameFactory) classInstance.newInstance();
98                  if (gameFactoriesList.contains(gameFactory)) {
99                      JOptionPane.showMessageDialog(null,
100                             files[i].getName() + " has been included twice.",
101                             "Error loading a game", JOptionPane.WARNING_MESSAGE);
102                     continue;
103                 }
104                 if (SimpleGameNetSettings.getInstance().getVersion().compareTo(
105                         gameFactory.getMinimumSimpleGameNetVersion())
106                         < 0) {
107                     JOptionPane.showMessageDialog(null,
108                             files[i].getName() + " needs SimpleGameNet version "
109                             + gameFactory.getMinimumSimpleGameNetVersion()
110                             .toString() + ".",
111                             "Error loading a game", JOptionPane.WARNING_MESSAGE);
112                     continue;
113                 }
114                 gameFactoriesList.add(gameFactory);
115 //               //--
116 //               for (Enumeration e = jarFile.entries(); e.hasMoreElements(); ) {
117 //                  String className = ( (ZipEntry) e.nextElement() ).getName();
118 //                  if (className != null && className.endsWith(".class") ) {
119 //                     className = className.substring(0, className.length() - 6);
120 //System.out.println("loading " + className);
121 //                     classLoader.loadClass(className);
122 //                  }
123 //               }
124 //               //--
125             } catch (Exception e) {
126                 JOptionPane.showMessageDialog(null,
127                         files[i].getName() + " is not a valid game package.",
128                         "Error loading a game", JOptionPane.WARNING_MESSAGE);
129             }
130         }
131         if (gameFactoriesList.size() <= 0) {
132             JOptionPane.showMessageDialog(null,
133                     pathFile.toString()
134                     + " did not contain any valid game packages.",
135                     "Error loading games", JOptionPane.ERROR_MESSAGE);
136             System.exit(1);
137         }
138         return gameFactoriesList;
139     }
140 
141 
142     private ClassLoader gamesClassLoader;
143     private List gameFactoriesList;
144 
145     private GameFactoryManager(ClassLoader gamesClassLoader, List gameFactoriesList) {
146         this.gamesClassLoader = gamesClassLoader;
147         this.gameFactoriesList = gameFactoriesList;
148     }
149 
150     public ClassLoader getGamesClassLoader() {
151         return gamesClassLoader;
152     }
153 
154     public GameFactory[] getGameFactories() {
155         return (GameFactory[]) gameFactoriesList.toArray(new GameFactory[gameFactoriesList.size()]);
156     }
157 
158     public GameFactory getGameFactory(GameIdentification gameIdentification) {
159         for (Iterator it = gameFactoriesList.iterator(); it.hasNext();) {
160             GameFactory gameFactory = (GameFactory) it.next();
161             if (gameFactory.getName().equals(gameIdentification.getName())
162                     && gameFactory.getAuthor().equals(gameIdentification.getAuthor())) {
163                 return gameFactory;
164             }
165         }
166         return null;
167     }
168 
169     private static class JarFileFilter implements FileFilter {
170 
171         public boolean accept(File pathname) {
172             return pathname.getName().endsWith(".jar");
173         }
174 
175     }
176 
177 }