Refactor.
[hs-java.git] / Java / ClassPath / Common.hs
1
2 module Java.ClassPath.Common where
3
4 import Data.List
5 import Data.String.Utils (split)
6
7 import Java.ClassPath.Types
8
9 mapF ::  (t -> a) -> [Tree t] -> [Tree a]
10 mapF fn forest = map (mapT fn) forest
11
12 mapFM fn forest = mapM (mapTM fn) forest
13
14 mapTM fn (Directory dir forest) = Directory dir `fmap` mapFM fn forest
15 mapTM fn (File a) = File `fmap` fn a
16
17 mapT ::  (t -> a) -> Tree t -> Tree a
18 mapT fn (Directory dir forest) = Directory dir (mapF fn forest)
19 mapT fn (File a) = File (fn a)
20
21 buildTree :: [FilePath] -> [Tree FilePath]
22 buildTree strs =
23   let build :: [[String]] -> [Tree FilePath]
24       build [[name]] = [File name]
25       build ss = map node $ groupBy eq (sort ss)
26
27       node [] = error "Impossible: groupBy give an empty group!"
28       node ([]:l) = node l
29       node l | all (null . tail) l = File (head $ head l)
30              | otherwise           = Directory (head $ head l) (build $ map tail l)
31
32       ls = map (split "/") strs
33
34       eq [] []       = True
35       eq (x:_) (y:_) = x == y
36
37   in  build ls
38
39 merge :: [Tree CPEntry] -> [Tree CPEntry]
40 merge [] = []
41 merge [t1,t2] = merge1 [t1] t2
42 merge (t:ts) = foldl merge1 [t] ts
43   
44 merge1 :: [Tree CPEntry] -> Tree CPEntry -> [Tree CPEntry]
45 merge1 [] x = [x]
46 merge1 (x@(File e): es) y@(File e') | e == e'   = x: es
47                                     | otherwise = x: merge1 es y
48 merge1 (d@(Directory _ _):es) f@(File _) = d: merge1 es f
49 merge1 (x@(Directory dir f):es) y@(Directory dir' f')
50   | dir == dir' = Directory dir (merge $ f ++ f'): es 
51   | otherwise   = x: merge1 es y
52