Cleanup, minor updates.
[hs-java.git] / Java / JAR.hs
1
2 module Java.JAR 
3   (readManifest,
4    readJAR,
5    addJAR
6   ) where
7
8 import Control.Monad.Trans (liftIO)
9 import qualified Control.Monad.State as St
10 import Data.List
11 import qualified Codec.Archive.LibZip as Zip
12
13 import Java.ClassPath
14 import Java.JAR.Archive
15 import Java.META
16
17 readManifest :: Zip.Archive (Maybe Manifest)
18 readManifest = do
19   let manifestPath = "META-INF/MANIFEST.MF"
20   files <- Zip.fileNames []
21   if manifestPath `elem` files
22     then do
23          content <- Zip.fileContents [] manifestPath
24          case parseMeta content of
25            Left e -> fail $ show e
26            Right meta -> return $ Just (loadSpec meta)
27     else return Nothing
28
29 readOne :: FilePath -> String -> Zip.Archive [Tree CPEntry]
30 readOne jarfile str = do
31     files <- Zip.fileNames []
32     return $ mapF (NotLoadedJAR jarfile) (buildTree $ filter good files)
33   where
34     good name = str `isPrefixOf` name
35
36 -- | Read entries from JAR file, using MANIFEST.MF if it exists.
37 readJAR :: FilePath -> IO [Tree CPEntry]
38 readJAR jarfile = do
39   r <- Zip.withArchive [] jarfile $ do
40          m <- readManifest
41          case m of
42            Nothing -> return Nothing
43            Just mf -> do
44                       trees <- mapM (readOne jarfile) (map meName $ manifestEntries mf)
45                       let forest = merge (concat trees)
46                       return (Just forest)
47   case r of
48     Nothing -> readAllJAR jarfile
49     Just f  -> return f
50
51 -- | Add given JAR file to ClassPath
52 addJAR :: FilePath -> ClassPath ()
53 addJAR jarfile = do
54   classes <- liftIO $ readJAR jarfile
55   cp <- St.get
56   let cp' = merge $ cp ++ classes
57   St.put cp'
58