public interface PerfStatistics {
    String getOpenJPAStatistics();
    String getEntityClasses();
    String getEhCacheManager();
}

@Stateless
public class PerfStatisticsImpl implements PerfStatistics {
    @Inject
    private EntityManagerJPAFactory entityManagerFactory;
    private OpenJPAEntityManagerFactory openJPAEntityManagerFactory;

    @PostConstruct
    public void init() {
        openJPAEntityManagerFactory = OpenJPAPersistence.cast(entityManagerFactory.getEntityManager().getEntityManagerFactory());
    }

    @Override
    public String getOpenJPAStatistics() {
        StoreCache cache = openJPAEntityManagerFactory.getStoreCache();

        CacheStatistics st = cache.getStatistics();
        return String.format("{ \"ReadCount\": %d, \"HitCount\": %d, \"WriteCount\": %d }", st.getReadCount(), st.getHitCount(), st.getWriteCount());
    }

    @Override
    public String getEntityClasses() {
        StringBuilder res = new StringBuilder("{ \"Entities\": [");

        EntityManagerFactory emf = openJPAEntityManagerFactory;
        EntityManager em = emf.createEntityManager();
        Cache cache = emf.getCache();
        for(EntityType<?> entityType : em.getMetamodel().getEntities()) {
            Class<?> cls = entityType.getBindableJavaType();
            res.append(String.format("\"%s\", ", cls.getCanonicalName()));
        }
        res.append("\"\"], \"Cache\": \"");
        res.append(cache.toString());
        res.append("\" }");
        return res.toString();
    }

    @Override
    public String getEhCacheManager() {
        List<CacheManager> tmpMgr = CacheManager.ALL_CACHE_MANAGERS;
        StringBuilder res = new StringBuilder("{ \"count:\": ");
        res.append(tmpMgr.size());
        res.append(", \"CacheManagers\": [");
        for(CacheManager cm : tmpMgr) {
            res.append(String.format("{ \"name\": \"%s\", \"caches\": [", cm.getName()));
            String[] cacheNames = cm.getCacheNames();
            for (String cacheName : cacheNames) {
                net.sf.ehcache.Cache ec = cm.getCache(cacheName);
                Statistics stat =  ec.getStatistics();
                res.append(String.format("{ \"name\": \"%s\", \"status\": \"%s\", \"CacheHits\": %d, \"CacheMisses\": %d, \"ObjectCount\": %d, \"AvgGetTime\": %f, \"AvgSearchTime\": %d }, "
                        , cacheName, ec.getStatus(), stat.getCacheHits(), stat.getCacheMisses(), stat.getObjectCount()
                        , stat.getAverageGetTime(), stat.getAverageSearchTime()));
            }
            res.append("\"\"] }, ");
        }
        res.append("{}] }");
        return res.toString();
    }
}
