2013-05-25 3 views
2

Я работаю над игровой системой. Пользователи могут отправлять файлы .class и .java для индивидуального поведения. Некоторые объекты доставляются пользователю через обратный вызов, но если пользователь может сам построить этот объект (с пользовательскими параметрами), это будет означать для него преимущество. Я откажусь от размышлений для пользователя и запечатаю свои пакеты. Я могу заставить это работать, если я откажусь от всей структуры пакета (и сделаю конструкторы package-private), но я бы не хотел этого делать.Разрешение строительства объекта только с некоторых пакетов


Вот пример:

sscce.mycode.a.SomeClass.java:

package sscce.mycode.a; 

import sscce.mycode.b.RestrictedObject; 
import sscce.usercode.SomeUserClass; 

public class SomeClass { 

    public static void main(String[] args) { 
     SomeUserClass userClass=new SomeUserClass(); 

     // If I can create it from here, anyone can... 
     RestrictedObject object=new RestrictedObject(); 

     userClass.someMethod(object); 
    } 

} 

sscce.mycode.b.Interface.java:

package sscce.mycode.b; 

public interface Interface { 

    public void someMethod(RestrictedObject restrictedObject); 

} 

sscce.mycode.b.RestrictedObject.java:

package sscce.mycode.b; 

public class RestrictedObject { 

    public RestrictedObject() {} 

} 

sscce.usercode.SomeUserClass.java:

package sscce.usercode; 

import sscce.mycode.b.Interface; 
import sscce.mycode.b.RestrictedObject; 

public class SomeUserClass implements Interface { 

    @Override 
    public void someMethod(RestrictedObject restrictedObject) { 
     // It receives an instance, but cannot create it. 
     System.out.println("Got "+restrictedObject); 
    } 
} 

Мотивация: Имея все в одном пакете звучит неряшлив ...

Есть ли у кого-нибудь идеи о том, как это сделать без выравнивания t он упаковывает?
Заранее спасибо за любые решения, идеи или комментарии, Till

+0

Как отказаться от структуры упаковки поможет вам это сделать? – Keppil

+0

@ Keppil: Я мог бы сделать конструкторы private-package, построить их в пакете и передать их пользователю. – tilpner

ответ

1

Вы можете сделать это следующим образом, однако вы должны тщательно рассмотреть, если вы действительно хотите использовать этот подход, поскольку он очень медленно, и, откровенно говоря, плохая практика , я положу его в любом случае, как вы можете сделать это:

public final class Secured { 

    private static final Set<Class<?>> allowedCallers = new HashSet<>(); 

    static { 
    allowedCallers.add(Allowed.class); 
    } 

    private static final class SecurityManagerExtension extends SecurityManager { 

    private static final int OFFSET = 4; 

    @Override 
    protected Class<?>[] getClassContext() { 
     return super.getClassContext(); 
    } 

    private Class<?> getCaller() { 
     try { 
     return getClassContext()[OFFSET]; 
     } catch (ArrayIndexOutOfBoundsException e) { 
     return null; 
     } 
    } 
    } 

    private Secured() { 
    // protect against reflection attack 
    Class<?> caller = new SecurityManagerExtension().getCaller(); 
    if (!this.getClass().equals(caller)) { 
     throw new IllegalStateException(); 
    } 
    System.out.println("Secured instance constructed!"); 
    } 

    public static Secured createInstance() { 
    // this gets the class name of the calling class 
    Class<?> caller = new SecurityManagerExtension().getCaller(); 
    if (allowedCallers.contains(caller)) { 
     System.out.println("Created instance by '" + caller + "'!"); 
     return new Secured(); 
    } else { 
     System.out.println("No instance created because call was made by '" + caller + "'!"); 
     return null; 
    } 
    } 
} 

Обратите внимание на окончательное ключевое слово в классе, чтобы предотвратить подклассы. Если вам нужно подклассифицировать класс самостоятельно, переместите последнее ключевое слово на заводский метод. Также обратите внимание, что это не защищено от атак сериализации.

+0

Ничего себе, спасибо большое! Это (почти) идеально. Если лучшие решения не будут опубликованы, я приму ваш ответ и использую этот подход. – tilpner

Смежные вопросы