Поскольку в Java еще нет какого-либо механизма контроля доступа, кроме модификаторов доступа (частного, защищенного, общедоступного или ничего для доступа с защитой пакетов), я могу предложить вам следующее решение.
Все классы должны быть защищены пакетами. Чтобы иметь возможность вызывать свои собственные классы из другого пакета, создайте открытые интерфейсы в ваших пакетах и заставьте свои классы реализовывать эти интерфейсы. Экземпляры классов должны создаваться только вашей фабрикой. Положите фабрику за пакет. Сам фабричный класс является публичным.
Теперь у клиентского кода есть только одна возможность доступа к вашим классам: создать их экземпляр с помощью вашей фабрики. Но завод должен проверить права доступа звонящего. Это просто: new Throwable().getStackTrace()[0]
возвращает вам элемент трассировки стека вашего абонента. Изучите его пакет и решите, следует ли вам продолжать или бросить Exception
, например, SecurityException
.
Есть и другие решения. Например, вы можете обернуть все ваши классы, используя аспекты. Например, используйте AspectJ, который выполняет модификацию байтового кода и автоматически вставляет некоторый код. Этот код проверит права доступа и выдаст исключение, как описано выше. Это решение, вероятно, лучше, но требует, чтобы вы немного узнали об AspectJ.