2 module JAR.Archive where
4 import Control.Monad.Trans
5 import qualified Control.Monad.State as St
6 import qualified Codec.Archive.LibZip as Zip
8 import Data.String.Utils (split)
9 import qualified Data.ByteString.Lazy as B
15 readJAR :: FilePath -> IO [Tree CPEntry]
17 files <- Zip.withArchive [] jarfile $ Zip.fileNames []
18 return $ mapF (NotLoadedJAR jarfile) (buildTree files)
20 readFromJAR :: FilePath -> FilePath -> IO (Class Direct)
21 readFromJAR jarfile path = do
22 content <- Zip.withArchive [] jarfile $ Zip.fileContents [] path
23 let bstr = B.pack content
24 return $ classFile2Direct (decode bstr)
26 addJAR :: FilePath -> ClassPath ()
28 classes <- liftIO $ readJAR jarfile
30 let cp' = merge $ cp ++ classes
33 loadClass :: String -> ClassPath ()
36 cp' <- liftIO $ mapM (load xs) cp
41 load :: [String] -> Tree CPEntry -> IO (Tree CPEntry)
43 load (p:ps) t@(Directory dir forest)
44 | p == dir = Directory dir `fmap` mapM (load ps) forest
45 | otherwise = return t
46 load [p] t@(File (NotLoaded f))
47 | (p ++ ".class") == f = do
48 cls <- parseClassFile (path ++ ".class")
49 return (File $ Loaded path cls)
50 | otherwise = return t
51 load [p] t@(File (NotLoadedJAR jarfile f))
52 | (p ++ ".class") == f = do
53 cls <- readFromJAR jarfile (path ++ ".class")
54 return (File $ LoadedJAR jarfile cls)
55 | otherwise = return t
56 load ps (File _) = fail $ "Found file when expecting directory! " ++ show ps