55
66package org .eolang ;
77
8- import java .io .File ;
98import java .lang .reflect .InvocationTargetException ;
10- import java .nio .file .Files ;
11- import java .nio .file .Path ;
12- import java .nio .file .Paths ;
139import java .util .Map ;
1410import java .util .concurrent .ConcurrentHashMap ;
1511
@@ -69,18 +65,35 @@ public boolean hasRho() {
6965
7066 @ Override
7167 public Phi take (final String name ) {
72- final String obj = String .join ("." , this .pkg , name );
73- final String key = new JavaPath (obj ).toString ();
74- return this .objects .computeIfAbsent (
75- key ,
76- k -> {
77- final Phi initialized = this .loadPhi (key , obj );
78- if (!(initialized instanceof PhPackage )) {
79- initialized .put (Attr .RHO , this );
80- }
81- return initialized ;
68+ final String fqn = String .join ("." , this .pkg , name );
69+ final Phi taken ;
70+ if (name .equals (Attr .RHO )) {
71+ if (this .objects .containsKey (Attr .RHO )) {
72+ taken = this .objects .get (Attr .RHO );
73+ } else {
74+ throw new ExUnset (
75+ String .format (
76+ "The %s attribute is absent in package object '%s'" ,
77+ Attr .RHO , this .pkg
78+ )
79+ );
8280 }
83- ).copy ();
81+ } else if (this .objects .containsKey (fqn )) {
82+ taken = this .objects .get (fqn ).copy ();
83+ } else if (name .contains ("." )) {
84+ final String [] parts = name .split ("\\ ." );
85+ Phi next = this .take (parts [0 ]);
86+ for (int idx = 1 ; idx < parts .length ; ++idx ) {
87+ next = next .take (parts [idx ]);
88+ }
89+ taken = next ;
90+ } else {
91+ final Phi loaded = this .loadPhi (fqn );
92+ loaded .put (Attr .RHO , this );
93+ this .put (fqn , loaded );
94+ taken = this .take (name );
95+ }
96+ return taken ;
8497 }
8598
8699 @ Override
@@ -99,9 +112,7 @@ public void put(final int pos, final Phi object) {
99112
100113 @ Override
101114 public void put (final String name , final Phi object ) {
102- throw new ExFailure (
103- "Can't #put(%s, %s) to package object \" %s\" " , name , object , this .pkg
104- );
115+ this .objects .put (name , object );
105116 }
106117
107118 @ Override
@@ -111,43 +122,41 @@ public byte[] delta() {
111122
112123 /**
113124 * Load phi object by package name from ClassLoader.
114- * @param path Path to directory or .java file
115- * @param object Object FQN
116125 * @return Phi
117126 */
118- private Phi loadPhi (final String path , final String object ) {
119- final Path pth = new File (
120- this .getClass ().getProtectionDomain ().getCodeSource ().getLocation ().getPath ()
121- ).toPath ().resolve (path .replace ("." , File .separator ));
122- final Phi phi ;
123- if (Files .exists (pth ) && Files .isDirectory (pth )) {
124- phi = new PhPackage (object );
125- } else {
126- final Path clazz = Paths .get (String .format ("%s.class" , pth ));
127- if (!Files .exists (clazz ) || Files .isDirectory (clazz )) {
128- throw new ExFailure (
129- String .format ("Couldn't find object '%s'" , object )
130- );
131- }
127+ private Phi loadPhi (final String fqn ) {
128+ final String target = new JavaPath (fqn ).toString ();
129+ Phi loaded ;
130+ try {
131+ Class .forName (String .format ("%s.package-info" , target ));
132+ loaded = new PhPackage (fqn );
133+ } catch (final ClassNotFoundException pckg ) {
132134 try {
133- phi = (Phi ) Class .forName (path )
135+ loaded = (Phi ) Class .forName (target )
134136 .getConstructor ()
135137 .newInstance ();
136- } catch (final ClassNotFoundException
137- | NoSuchMethodException
138- | InvocationTargetException
139- | InstantiationException
140- | IllegalAccessException ex
138+ } catch (final ClassNotFoundException phi ) {
139+ throw new ExFailure (
140+ String .format (
141+ "Couldn't find object '%s' because there's no class or package '%s'" ,
142+ fqn , target
143+ ),
144+ phi
145+ );
146+ } catch (final NoSuchMethodException
147+ | InvocationTargetException
148+ | InstantiationException
149+ | IllegalAccessException ex
141150 ) {
142151 throw new ExFailure (
143152 String .format (
144153 "Couldn't build Java object \" %s\" in EO package \" %s\" " ,
145- path , this .pkg
154+ target , this .pkg
146155 ),
147156 ex
148157 );
149158 }
150159 }
151- return phi ;
160+ return loaded ;
152161 }
153162}
0 commit comments